﻿/**
 * @author pop webdev [cn]
 * @version: 0.6.
 * @classDescription: Content Carousel
 * @dependencies: Prototype v1.6.1.
 */

// start GalleryCarousel
var GalleryCarousel = Class.create ({
	initialize: function(target,container,track,items,links,lnkPrev,lnkNext,options,flashOptions)
	{
		// ** set initial values ** //
		this.target = target;						// $ primary photo or video
		this.targetID = this.target.identify();		// target ID as a string (used for Flash embedSWF)
		this.targetParent = this.target.up();		// $ target parent element (used for Flash embedSWF)
		this.container = container;					// $ container for the entire widget
		this.track = track;							// $ inner track containes indi items
		this.items = items;							// $$ all the items in the carousel
		this.links = $$(links);						// $$ all the item links, passed in as a string in order to set dynamically
		this.length = this.items.size();			// length of items
		this.lnkLength = this.links.size();			// length of links
		this.lnkPrev = lnkPrev;						// $ previous link
		this.lnkNext = lnkNext;						// $ next link
		this.track.writeAttribute('role', 'listbox');					// add aria role 'listbox' to track
		this.items.invoke('writeAttribute', 'role', 'option');			// add aria role 'option' carousel items
		this.lnkPrev.writeAttribute('aria-controls', this.trackID);		// add aria role to prev link
		this.lnkNext.writeAttribute('aria-controls', this.trackID);		// add aria role to next link
		this.options = Object.extend({
			isVideoGallery: false,					//
			initialIndex: 0,						// index of initial item
			itemsPerGroup: 1,						// items per group
			visibleItems: 4,						// number of items visible
			speed: 0.5,								// animation speed
			appearEffect: false,					// boolean: animation effect
			activeItemClassName: 'active',			// css class for active tab links, not used for this object
			disabledLinkClassName: 'disabled',		// disabled class for prev/next links
			loops: false							// boolean: enable 'infinite' looping
		}, options || {});
		this.flashOptions = Object.extend({
			stageWidth: '480',
			stageHeight: '390',
			videoWidth: '480',
			videoHeight: '360',
			bgcolor: '#ffffff',
			version: '9.0.0',
			swfPath: 'videoplayer.swf',
			autoPlay: false							// boolean: enable autoplay on page load
		}, flashOptions || {});
		this.flashOptions = this.options.isVideoGallery ? this.flashOptions : null;
		this.isAnimating = false;																			// boolean: flag for animation-in-progress
		if (this.options.initialIndex >= this.length) {this.options.initialIndex = 0;}						// reset initial index if too high
		if (this.length <= this.options.visibleItems) {this.options.loops = false;}							// short-circuit loops option if not enough items

		// ** set initial conditions ** //
		this.currentIndex = this.options.initialIndex;														// current index = first item
		this.nextIndex = this.currentIndex;																	// check against curentIndex when looping
		this.scrollAmt = (this.items[0].getWidth() * -1);													// amt to scroll by = items width
		if (this.options.loops)
		{
			this.cloneItems = this.track.innerHTML;															// create duplicate of items html
			this.track.insert({top: this.cloneItems}).insert({bottom: this.cloneItems});					// insert duplicate items for 'infinite' looping
			this.currentIndex += this.length;																// reset current index
			this.links = $$(links);																			// reset links
			this.lnkLength = this.links.size();
		}
		this.firstPos;													// declare first position (firstPos == initial index within duplicated 'top' items)
		this.lastPos;													// declare last position (lastPos == initial index within duplicated 'bottom' items)

		// ** bind events and go! ** //
		var boundClickHandler = this.__Click.bindAsEventListener(this);
		this.links.invoke('observe', 'click', boundClickHandler);											// observe item link click
		this.lnkPrev.observe('click', this.__ClickPrev.bindAsEventListener(this));							// observe prev link click
		this.lnkNext.observe('click', this.__ClickNext.bindAsEventListener(this));							// observe next link click
		this.setInitialPos();																				// init position of track
		if (this.length <= this.options.visibleItems)
		{
			this.lnkPrev.addClassName(this.options.disabledLinkClassName);									// disable previous link if not enough items
			this.lnkNext.addClassName(this.options.disabledLinkClassName);									// disable next link if not enough items
		}
    },
    setInitialPos: function()
    {
		if (this.options.loops)
		{
			this.firstPos = this.currentIndex - this.options.visibleItems;			// set firstPos to first item - num visible items
			this.lastPos = this.currentIndex * 2;									// set lastPos to first item of duplicate group
		} else {
			this.firstPos = 0;														// set firstPos to first item
			this.lastPos = this.length - this.options.visibleItems;					// set lastPos to last item - num visible items (adj -1 ?)
		}
		this.MoveIt(this.currentIndex);
    },
	__Click: function(e)
	{
		e.stop();
		var el = e.findElement('a');
		for (var i=0; i<this.lnkLength; i++)
		{
			if (this.links[i] == el)
			{
				this.currentIndex = i;
				if (this.length <= this.options.visibleItems)
				{
					if (this.options.isVideoGallery){
						this.SwapVideo(this.currentIndex);
					} else {
						this.SwapImage(this.currentIndex);
					}
				} else {
					this.MoveIt(this.currentIndex);
				}
				break;
			}
		}
	},
    __ClickPrev: function(e)
    {
        e.stop();
        //var el = e.findElement('a');
        if (!this.isAnimating && !this.lnkPrev.hasClassName(this.options.disabledLinkClassName))
        {
			if (this.options.loops)
			{
				this.currentIndex -= this.options.itemsPerGroup;
				this.MoveIt(this.currentIndex);
			} else {
				if (this.currentIndex != this.firstPos)
				{
					this.currentIndex -= this.options.itemsPerGroup;
					this.MoveIt(this.currentIndex);
				}
			}
        }
    },
    __ClickNext: function(e)
    {
        e.stop();
        //var el = e.findElement('a');
        if (!this.isAnimating && !this.lnkNext.hasClassName(this.options.disabledLinkClassName))
        {
			if (this.options.loops)
			{
				this.currentIndex += this.options.itemsPerGroup;
				this.MoveIt(this.currentIndex);
			} else {
				if (this.currentIndex != this.lastPos)
				{
					this.currentIndex += this.options.itemsPerGroup;
					this.MoveIt(this.currentIndex);
				}
			}
        }
    },
    MoveIt: function(index)
    {
		//this.currentIndex = index; // only currentIndex should ever be passed to MoveIt
		var moveTrack = new Effect.Move(this.track, {
			x: this.scrollAmt * index,
			y: 0,
			mode: 'absolute',
			fps: 100,
			duration: this.options.speed,
			transition: Effect.Transitions.easeOutExpo,
            beforeStart: function() {
                this.isAnimating = true;
				if (this.options.isVideoGallery){
					this.SwapVideo(index);
				} else {
					this.SwapImage(index);
				}
                this.UpdateLinks();
            }.bind(this),
            afterFinish: function() {
                this.isAnimating = false;
                this.AdjustPosition(index);
            }.bind(this)
		});
    },
    AdjustPosition: function(index)
    {
		if (this.options.loops)
		{
			if (index <= this.firstPos)
			{
				this.currentIndex += this.length;
				this.track.setStyle({left: (this.scrollAmt * this.currentIndex) + 'px'});
				this.links[this.currentIndex].up().addClassName(this.options.activeItemClassName);
			}
			if (index >= this.lastPos)
			{
				this.currentIndex -= this.length;
				this.track.setStyle({left: (this.scrollAmt * this.currentIndex) + 'px'});
				this.links[this.currentIndex].up().addClassName(this.options.activeItemClassName);
			}
		}
    },
    UpdateLinks: function()
    {
		this.lnkPrev.removeClassName(this.options.disabledLinkClassName);
		this.lnkNext.removeClassName(this.options.disabledLinkClassName);
		// set 'disabled' class on prev/next links
		if (!this.options.loops)
		{
			if (this.currentIndex == this.firstPos)
			{
				this.lnkPrev.addClassName(this.options.disabledLinkClassName);
			}
			if (this.currentIndex == this.lastPos)
			{
				this.lnkNext.addClassName(this.options.disabledLinkClassName);
			}
		}
	},
	SwapImage: function(index)
	{
		//update detail img
		this.target.setOpacity(0);
		this.target.src = this.links[index].href;
		this.target.alt = this.links[index].title;
		if (this.options.appearEffect)
		{
			this.target.appear({duration: this.options.speed});
		} else {
			this.target.setOpacity(1.0);
		}
		this.HighlightItem(index);
    },
	SwapVideo: function(index)
	{
		//get video details
		var lnkRel = this.links[index].rel.split(';');
		var videoType = lnkRel[0];
		var videoID = lnkRel[1];
		this.FlashInit(videoType,videoID);
		this.HighlightItem(index);
    },
	HighlightItem: function(index)
	{
        var activeClassName = this.options.activeItemClassName;
        this.links.each(function(el, index) {
			el.up().removeClassName(activeClassName);				// un-highlight all links parents
		});
		this.links[index].up().addClassName(activeClassName);		// highlight specific link parent
	},
    FlashInit: function(videoType,videoID)
    {
		var flash = $(this.targetID);
		flash.remove();
		this.targetParent.insert(this.target);
		if (videoType == 'youtube')
		{
			this.PlayYouTube(videoID);
		}
		if (videoType == 'vimeo')
		{
			this.PlayVimeo(videoID);
		}
		if (videoType == 'local')
		{
			this.PlayLocalVideo(videoID); // videoID = url for local videos
		}
    },
    PlayYouTube: function(videoID)
    {
	    this.container.fire('flashplayer:triggered', {videoType: 'youtube', videoID: videoID});
	    var flashvars = {
			autoPlayBool: this.flashOptions.autoPlay ? 'true' : 'false',
			loopBool: 'false',
			playerPath: 'http://www.youtube.com/apiplayer?version=3',
			videoWidth: this.flashOptions.videoWidth,
			videoHeight: this.flashOptions.videoHeight,
			videoID: videoID
		};
	    var params = {
			allowFullScreen: 'true',
			allowScriptAccess: 'always',
			autoplay: this.flashOptions.autoPlay ? 'true' : 'false',
			loop: 'false',
			menu: 'true',
			quality: 'high',
	    	salign: 't',
	    	scale: 'exactfit',
	    	wmode: 'opaque'
	    };
		var attributes = {
			bgcolor: this.flashOptions.bgcolor,
	    	id: this.targetID
		};
		swfobject.embedSWF(this.flashOptions.swfPath, this.targetID, this.flashOptions.stageWidth, this.flashOptions.stageHeight, this.flashOptions.version, false, flashvars, params, attributes);
		this.flashOptions.autoPlay = true;
    },
    PlayVimeo: function(videoID)
    {
	    this.container.fire('flashplayer:triggered', {videoType: 'vimeo', videoID: videoID});
	    var flashvars = {
			clip_id: videoID,
			autoplay: this.flashOptions.autoPlay ? 1 : 0,
			fullscreen: 1,
			js_api: 1,
			show_byline: 0,
			show_portrait: 0,
			show_title: 0,
			js_onLoad: 'vimeo_player_loaded',
			js_swf_id: 'moogaloop'
		};
	    var params = {
			allowFullScreen: 'true',
			allowScriptAccess: 'always',
			autoplay: this.flashOptions.autoPlay ? 'true' : 'false',
	    	wmode: 'opaque'
	    };
		var attributes = {
			bgcolor: this.flashOptions.bgcolor,
	    	id: this.targetID
		};
		swfobject.embedSWF('http://vimeo.com/moogaloop.swf', this.targetID, this.flashOptions.stageWidth, this.flashOptions.stageHeight, this.flashOptions.version, false, flashvars, params, attributes);
		this.flashOptions.autoPlay = true;
    },
    PlayLocalVideo: function(videoPath)
    {
		this.container.fire('flashplayer:triggered', {videoType: 'local', videoID: videoPath}); // videoID = url for local videos
	    var flashvars = {
			videoWidth: this.flashOptions.videoWidth,
			videoHeight: this.flashOptions.videoHeight,
			videoPath: videoPath,
			loopBool: 'false',
			autoPlayBool: 'false',
			hideControlsBool: 'false'
		};
	    var params = {
			allowFullScreen: 'true',
			allowScriptAccess: 'always',
			autoplay: this.flashOptions.autoPlay ? 'true' : 'false',
			loop: 'false',
			menu: 'true',
			quality: 'high',
	    	salign: 't',
	    	scale: 'exactfit',
	    	wmode: 'opaque'
	    };
		var attributes = {
			bgcolor: this.flashOptions.bgcolor,
	    	id: this.targetID
		};
		swfobject.embedSWF(this.flashOptions.swfPath, this.targetID, this.flashOptions.stageWidth, this.flashOptions.stageHeight, this.flashOptions.version, false, flashvars, params, attributes);
		this.flashOptions.autoPlay = true;
    }
});
// end GalleryCarousel

