/*
Script: RotoPhoto.js
	A RotoPhoto for MooTools.

* Created By Tim Kock

Licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported.
please see: http://creativecommons.org/licenses/by-nc-nd/3.0/

Should infringement of this license be detected, immediate legal action will be taken.

*/
var RotoPhoto = new Class({
	Implements: [Options, Events],
	options: {
		animationDuration: 250,
		addDefaultCss: true,
		assetBaseUrl: '../scripts/RotoPhoto/resources/',
		Debugging: false,
		preText: 'roto-text',
		width: 225,
		height: 325
	},

	initialize: function(name, element, options){
		this.name = name;
		this.setOptions(options);
		this.element = $(element);
		if(this.options.addDefaultCss) this.InjectCss();
		window.addEvent('domready', this.InjectElements.bind(this));
	},
	
	Reset: function() {
		if($(this.options.preText)) $(this.options.preText).destroy();
		this.isloaded = false;
		this.loadervisible = false;
		this.imageArray = new Array();
		this.previmage = -1;
		this.moved = false;
	},
	
	Load: function(baseName, startIndex, endIndex) {
				
		//Reset State
		this.Reset();
		
		// Show Loader
		this.ShowLoader();
		
		// Get File List
		this.ImageList = this.Files(baseName, startIndex, endIndex);
		this.image.src = this.ImageList[0];
		
		// Preload Images
		if (this.msgdiv != null)
		 	this.msgdiv.innerHTML = "Loading Images";
		for (var i = 0; i < this.ImageList.length; i++) {
			this.imageArray[i] = new Image;
			this.imageArray[i].src = this.ImageList[i];  // initiate image fetch
		}
	
		// images will start loading; we'll start a timer so that we
		// can monitor the progress of the loading at each timeout
		setTimeout(this.name + '.TimeOut()', 100);
		
		return this;
	}, 
	
	Files: function(baseName, startIndex, endIndex, fileType) {
		var fileList = new Array();
		var n = 0;
		if (typeof fileType == 'undefined')
			fileType = "jpg";  // default file type
		if (startIndex < endIndex)
			for (var i = startIndex; i <= endIndex; i++)
			fileList[n++] = baseName + i + "." + fileType;
		else
			for (var i = startIndex; i >= endIndex; i--)
			fileList[n++] = baseName + i + "." + fileType;
		return fileList;
	},
	
	InjectElements: function(){
		
		// Container Image
		this.image = new Element('img', {
			id: 'roto-image',
			styles: {
				visibility: 'hidden',
				width: this.options.width,
				height: this.options.height
			}
		}).inject(this.element);
		
		// Hook Events
		this.image.addEvent('click', this.MouseClick.bind(this));
		this.image.addEvent('mousemove', this.MouseMove.bind(this));
		
		// Loader Element
		this.loader = new Element('div', {
			id: 'roto-loader',
			styles: {
				visibility: 'hidden',
				width: this.options.width
			}
		}).inject(this.element);
		
		// Loader Table
		this.ctable = new Element('table', {
			align: 'center',
			border:	0,
			cellspacing: 0,
			cellpadding: 0
		}).inject(this.loader);
		
		// Loader Table Structure
		this.crow = new Element('tr').inject(this.ctable);
		this.colone = new Element('td').inject(this.crow);
		this.coltwo = new Element('td', {
			width: 5,
			html: '&nbsp;'
		}).inject(this.crow);
		this.colthr = new Element('td', {
			width: 32,
			height: 32,
			valign: 'middle'
		}).inject(this.crow);
		
		// Loader Content
		this.msgdiv = new Element('div', {
			id: 'roto-msg',
			align: 'right',
			html: 'Loading'
		}).inject(this.colone);
		this.ldrimg = new Element('img', {
			id: 'roto-ldrimg',
			src: this.options.assetBaseUrl + 'loader.gif',
			styles: {
				paddingTop: 2
			}
		}).inject(this.colthr);

	},
	
	InjectCss: function(){
		window.addEvent('domready', function(){
			if($('RotoCss')) return;
			new Element('link', {
				rel: 'stylesheet', 
				media: 'screen', 
				type: 'text/css', 
				href: this.options.assetBaseUrl + 'rotophoto.css',
				id: 'RotoCss'
			}).inject(document.head);
		}.bind(this));
	},
	
	TimeOut: function() {
		var isReady = 0;
		with (this) {
	
			var loaded = 0;
			for (var i = 0; i < imageArray.length; i++) {
				// when an img is loaded, it's readyState will be 'complete' (IE)
				// or 'complete' property will be true (Moz)
				if ((imageArray[i].readyState == 'complete') || imageArray[i].complete)
					loaded++;
			}
			if ((loaded < imageArray.length) && (msgdiv != null))
				msgdiv.innerHTML = "Loading " + (loaded + 1) + " of " + imageArray.length;
			if (loaded == imageArray.length) {
				MoveLoader();
				isloaded = true;
				if(this.image.getStyle('visibility')=='hidden') this.image.tween('opacity', [0,1]);
				if (msgdiv != null)
					msgdiv.innerHTML = "Move mouse right to left.";
			} else {
				setTimeout(name + '.TimeOut()', 100);  // set up for another poll
			}
		}
	},
	
	MouseMove: function (e) {
		// Called when the mouse moves over the image
		with (this) {
			if (isloaded && loadervisible) { 
				
				// Gather Event Information
				if (!e) var e = window.event;
				var posx = e.event.clientX-image.x;
				var posy = e.event.clientY-image.y;
				var n = Math.floor(posx / (options.width / imageArray.length))+1;
				
				// Output Debugging Information
				if(options.Debugging)
					msgdiv.innerHTML = 'x: ' + posx + ' y: ' + posy + ' n: ' + n;

				// Adjust Results
				if (n > imageArray.length)
					n = imageArray.length;          // make sure we're in range
				if (n != previmage) {               // do nothing if image is already displayed
					image.src = ImageList[n - 1];  	// change to desired image
					previmage = n;                  // record which image is now being displayed
				}
				
			}
		}
	},
	
	MouseClick: function() {
		if(this.loadervisible) {
			this.HideLoader();
		} else {
			this.ShowLoader();
		}
	},
	
	ShowLoader: function() {
		if(this.loader.getStyle('visibility')=='hidden') this.loader.tween('opacity', [0,1]);
		this.loadervisible = true;
	},
	
	HideLoader: function() {
		this.loader.tween('opacity', [1,0]);
		this.loadervisible = false;
	},
	
	MoveLoader: function() {
		if (this.moved != true) {
			this.loader.tween('top',10).setStyle('opacity', 1);
			this.ldrimg.src = this.options.assetBaseUrl + 'finished.gif',
			this.moved = true;
		} else {
			this.HideLoader();
		}
	}

});

