var FilmStrip = Class.create();

FilmStrip.prototype = {
	initialize: function(container) {
		this.imageMargin = 3;
		this.container = container;
		this.imagesLoaded = 0;
		this.allImagesLoaded = false;
		this.dragging = false;

		this.window = document.createElement('div');
		var imgHTML = this.container.innerHTML;
		this.container.innerHTML = '';
		this.window.innerHTML = imgHTML;
		Element.addClassName(this.window,'window');
		this.container.appendChild(this.window);
		
		this.cover = document.createElement('div');
		this.container.appendChild(this.cover);
		Element.addClassName(this.cover,'cover');
		this.cover.innerHTML = 'loading...';
		
		this.controls = document.createElement('div');
		this.container.appendChild(this.controls);
		this.controls.id = 'filmStripControls';
		this.controls.style.display = 'none';
		new Ajax.Updater(this.controls,'/js/filmstrip/controls.html', {method: 'get'});

		this.imageDivs = this.window.select('div.image');
		//this.images = this.window.getElementsByTagName('img');
		this.images = [];
		this.imageInfo = [];
		this.imageLinks = [];
		var imageLoaders = [];
		var link;
		for (i=0; i<this.imageDivs.length; i++) {
			this.images[i] = this.imageDivs[i].select('img')[0];
			link = this.imageDivs[i].select('a.info')[0];
			if (link == null) {
				this.imageInfo[i] = null;
				this.imageLinks[i] = null;
			}
			else {
				this.imageInfo[i] = link.innerHTML;
				this.imageLinks[i] = link.href;
			}
			
			imageLoaders[i] = new Image();
			imageLoaders[i].onload = this._imageLoaded.bind(this);
			imageLoaders[i].src = this.images[i].src;
		}

		// to deal with IE image loading bug, we poll in addition to using onload handler
		this.loadPE = new PeriodicalExecuter(this._checkImagesLoaded.bind(this),0.5);
		
		Event.observe(this.container,'mousedown', this.mousedown.bind(this));
		Event.observe(this.container,'mousemove', this.mousemove.bind(this));
		Event.observe(this.container,'mouseup', this.mouseup.bind(this));
		
		// create the strip's lightbox
		this.lightbox = new Lightbox(this);		
	},
	_checkImagesLoaded: function() {
		for (i=0; i<this.images.length; i++) {
			if (!this.images[i].complete)
				return;
		}
		
		this._loadComplete();
	},
	_imageLoaded: function() {
		this.imagesLoaded++;
		if (this.imagesLoaded == this.images.length) {
			this._loadComplete();
		}
		else {
			this.cover.innerHTML = 'loading...';
		}
	},
	_loadComplete: function() {
		if (this.allImagesLoaded)	// only run this once
			return;

		this.allImagesLoaded = true;
		this.loadPE.stop();
		
		var nextX = 0;
		for (var i=0; i<this.images.length; i++) {
			this.images[i].style.display = 'block';
			this.images[i].style.left = nextX+'px';
			this.images[i].style.zIndex = 1;
			this.images[i].myLeft = nextX;
			this.images[i].myIndex = i;
			nextX += Element.getWidth(this.images[i]) + this.imageMargin;
			
			Event.observe(this.images[i],'dblclick', this.imageDoubleClick.bind(this));
//			Event.observe(this.images[i],'mousedown', this.imageMousedown.bind(this));
//			Event.observe(this.images[i],'mousemove', this.imageMousemove.bind(this));
//			Event.observe(this.images[i],'mouseup', this.imageMouseup.bind(this));
		}
		this.totalImageWidth = nextX;
		this.leftIndex = 0;

		new Effect.Fade(this.cover, {duration: 1.0, beforeStart: this._firstStart.bind(this)});
		new Effect.Appear(this.controls, {duration: 1.0});
	},
	_firstStart: function() {
		var hash = window.location.hash.replace('#','');
		if (hash != '') {
			this.lightbox.start.bind(this.lightbox,hash).defer();
		}
		else {
			this.scrollToImage(0);
		}
	},
	
	imageMousedown: function(event) {
		this.imageClick = true;
	},
	imageMousemove: function(event) {
		this.imageClick = false;
	},
	imageMouseup: function(event) {
		if (this.imageClick) {
			index = Event.element(event).myIndex;
			this.scrollToImage(index);
			this.lightbox.start(index);
			this.imageClick = false;
		}
	},
	imageDoubleClick: function(event) {
		index = Event.element(event).myIndex;
		this.scrollToImage(index);
		this.lightbox.start(index);
	},
	
	mousedown: function(event) {
		this.dragging = true;
		this.clickX = Event.pointerX(event);
		Event.stop(event);
	},
	mousemove: function(event) {
		var pointerX = Event.pointerX(event);
		if(this.dragging) {
			if (this.jumpPe != null) this.jumpPe.stop();
			for(var i=0; i<this.images.length; ++i) {
				this.images[i].myLeft += pointerX - this.clickX;
				this.images[i].style.left = this.images[i].myLeft+'px';
			}
			this.clickX = pointerX;
			this.loopcheck();
		}
		Event.stop(event);
	},
	mouseup: function(event) {
		this.dragging = false;
		Event.stop(event);
		
//		this.scrollToImage(this.getCurrentImageIndex());
	},
	
	start: function() {
		if (this.jumpPe != null) this.jumpPe.stop();
		this.pe = new PeriodicalExecuter(this.scroll.bind(this),0.05);
		this.moving = true;
	},
	stop: function() {
		this.moving = false;
		this.pe.stop();
	},
	isMoving: function() {
		return this.moving;
	},
	
	scroll: function() {
		if (!this.dragging) {
			for (var i=0; i<this.images.length; i++) {
				this.images[i].myLeft-= 1;
				this.images[i].style.left = this.images[i].myLeft+'px';
			}
			this.loopcheck();
		}
	},
	
	scrollToImage: function(idx) {
		if (this.isMoving()) {
			this.stop();
		}

		this.scrollToIndex = idx;
		this.scrollToX = Math.round((this.container.getWidth()-this.images[idx].getWidth())*0.5);
		if (this.jumpPe != null) this.jumpPe.stop();
		this.jumpPe = new PeriodicalExecuter(this._scrollToImage.bind(this),0.025);
	},
	_scrollToImage: function() {
		var scrollImage = this.images[this.scrollToIndex];
		var delta = 1;
		var distanceLeft = scrollImage.myLeft-this.scrollToX;
		var inc;
		if (Math.abs(distanceLeft) < delta) {
			inc = distanceLeft;
			this.jumpPe.stop();
		}
		else {
			inc = Math.round((distanceLeft) * 0.12);
			if (inc == 0)
				inc = (distanceLeft < 0 ? -1 : 1);
		}
		
		for (var i=0; i<this.images.length; i++) {
			this.images[i].myLeft-= inc;
			this.images[i].style.left = this.images[i].myLeft+'px';
		}
		this.loopcheck();
	},
	getCurrentImageIndex: function() {
		// find the center of the strip
		var center = this.container.getWidth()/2;
		// the next image whose myLeft is greater than this is it.  start with image at leftIndex
		var theImage = this.images[this.leftIndex];
		var counter = 0;
		var theIndex;
		while (theImage.myLeft < center) {
			counter++;
			theIndex = (this.leftIndex+counter) % this.images.length;
			theImage = this.images[theIndex];
		}
		return (theIndex+this.images.length-1) % this.images.length;
	},
	nextImage: function() {
		var nextIndex = (this.getCurrentImageIndex()+1) % this.images.length;
		this.scrollToImage(nextIndex);
	},
	previousImage: function() {
		var previousIndex = (this.getCurrentImageIndex()+this.images.length-1) % this.images.length;
		this.scrollToImage(previousIndex);
	},
	
	loopcheck: function() {
		var leftImage = this.images[this.leftIndex];
		if(leftImage.myLeft < -leftImage.getWidth()) {
			leftImage.myLeft += this.totalImageWidth;
			leftImage.style.left = leftImage.myLeft+'px';
			this.leftIndex = (this.leftIndex+1) % this.images.length;
		}
		else if(leftImage.myLeft > 0) {
			var rightIndex = (this.leftIndex+(this.images.length-1)) % this.images.length;
			var rightImage = this.images[rightIndex];
			rightImage.myLeft -= this.totalImageWidth;
			rightImage.style.left = rightImage.myLeft+'px';
			this.leftIndex = rightIndex;
		}
	}
}

var strip;

function initFilmStrip() {
	var stripDiv = $('filmStrip');
	if (stripDiv != null) {
		strip = new FilmStrip($('filmStrip'));
	}
}

function toggleMovement() {
	if (strip.isMoving()) {
		strip.stop();
	}
	else {
		strip.start();
	}
}

function iClick() {
	var index = strip.getCurrentImageIndex();
	strip.lightbox.start(index);
}

function nextImage() {
	strip.nextImage();
}
function previousImage() {
	strip.previousImage();
}

//Event.observe(window,'load',initFilmStrip);
