/*************************************
 * resources/js/casestudy.js
 *
 * Design Kitchen
 * @author: Matthew Story
**************************************/
var CaseStudy = Class.create();
CaseStudy.prototype = {
	viewer: false,
	elements: [],
	effect: false,
	currentElementNumber: false,
	listeners: [],
	onElementChange: false,
	loopInterval: false,
	randomLoopInterval: false,
	duration: false,
	stopLoop: false,

	initialize: function(viewer, elements) {
		var defaults = {
			effect: false,
			nextElement: [],
			prevElement: [],
			onElementChange: function() {},
			wrap: false,
			loop: false,
			randomLoop: false,
			loopDuration: 10,
			hideControlsIfOne: true
		};
		var options = (arguments[2]) ? arguments[2]:{};
		Object.extend(defaults, options);
		if (defaults.nextElement) {
            defaults.nextElement = (defaults.nextElement.constructor == Array) ? defaults.nextElement:[defaults.nextElement];
        }
        if (defaults.prevElement) {
            defaults.prevElement = (defaults.prevElement.constructor == Array) ? defaults.prevElement:[defaults.prevElement];
        }
		

		this.viewer = $(viewer);
		this.elements = (elements.constructor == Array) ? elements:[elements];
		if (!elements.length) {
			return false;
		}
		
		for (var i=0;i<this.elements.length;i++) {
			this.viewer.appendChild($(this.elements[i]));
			this.hideElement(i);
		}

		//register page turn handlers
		for (var i=0;i<defaults.nextElement.length;i++) {
			
			this.registerNextElementListener(defaults.nextElement[i]);
			this.checkHideControl(defaults.nextElement[i], defaults.hideControlsIfOne);
			
		}
		for (var i=0;i<defaults.prevElement.length;i++) {
			this.registerPrevElementListener(defaults.prevElement[i]);
			this.checkHideControl(defaults.prevElement[i], defaults.hideControlsIfOne);
		}
		this.effect = defaults.effect;
		this.onElementChange = defaults.onElementChange;
		this.duration = defaults.loopDuration;
		this.wrap = defaults.wrap;
		
		//if random loop and loop are set random loop takes priority
		if (defaults.randomLoop) {
			this.setRandomLoopInterval();
		} else if (defaults.loop) {
			this.setLoopInterval();
		} else {
			//go to first element
			this.goToElement(1);
		}
	},

	destroy: function() {
		this.viewer = false;
		this.unregisterListeners();
		this.elements = false;
		this.elementNumber = 0;
		this.effect = false;
	},

	showElement: function(index) {
		if (this.effect) {
			new this.effect(this.elements[index]);
		} else {
			$(this.elements[index]).show();
		}
		
		return true;
	},
	
	checkHideControl: function(control, hide) {
		if (hide && this.elements.length == 1) {
			$(control).hide();
		}
	},

	hideElement: function(index) {
		$(this.elements[index]).hide();
		return true;
	},
	
	goToElement: function(elementNumber) {
		if (this.currentElementNumber != elementNumber) {
			if (this.currentElementNumber) {
				this.hideElement(this.currentElementNumber - 1);
			}
			this.showElement(elementNumber - 1);
			this.currentElementNumber = elementNumber;
			
			//fire user defined function
			this.onElementChange(this.currentElementNumber);
		}

		return true;
	},
	
	goToRandomElement: function() {
		this.goToElement(Math.floor((Math.random() * this.elements.length) + 1));
		
		return true;
	},
	
	setLoopInterval: function() {
		this.stopLoop = false;
		this.loopInterval = this.interval();

		return true;
	},

	setRandomLoopInterval: function() {
		this.stopLoop = false;
		this.randomLoopInterval = this.randomInterval();

		return true;
	},

	interval: function() {
		if (!this.stopLoop) {
			if (this.currentElementNumber != this.getElementCount()) {
				this.nextElement();
			} else {
				this.goToElement(1);
			}
			this.loopInterval = window.setTimeout(this.interval.bindAsEventListener(this), this.duration*1000);
		} else {
			this.goToElement(1);
			this.loopInterval = false;
		}

		return true;
	},

	randomInterval: function() {
		if (!this.stopLoop) {
			this.goToRandomElement();
			this.randomLoopInterval = window.setTimeout(this.randomInterval.bindAsEventListener(this), this.duration*1000);
		} else {
			this.goToElement(1);
			this.randomLoopInterval = false;
		}

		return true;
	},

	clearInterval: function() {
		this.stopLoop = true;
		return true;
	},

	nextElement: function() {
		var nextElement = Math.min(this.currentElementNumber+1,this.elements.length);
		if (this.currentElementNumber == this.elements.length && this.wrap) {
			nextElement = 1;
		}
		this.goToElement(nextElement);
		
		return true;
	},

	prevElement: function() {
		var prevElement = Math.max(this.currentElementNumber-1,1);
		if (this.currentElementNumber == 1 && this.wrap) {
			prevElement = this.elements.length;
		}
		this.goToElement(prevElement);

		return true;
	},

	registerNextElementListener: function(element) {
		var event = (arguments[1]) ? arguments[1]:'click';
		this.registerListener(element, event, this.nextElement.bindAsEventListener(this));

		return true;
	},

	registerPrevElementListener: function(element) {
		var event = (arguments[1]) ? arguments[1]:'click';
		this.registerListener(element, event, this.prevElement.bindAsEventListener(this));

		return true;
	},

	bindEventToElement: function(elementNumber, element) {
		var event = (arguments[2]) ? arguments[2]:'click';
		var listener = this.goToElement.bindAsEventListener(this);
		this.registerListener(element, event, function() {
			listener(elementNumber);
		});

		return true;
	},
   	
	getElementCount: function() {
		return this.elements.length;
	},

	registerListener: function(element, event, handler) {
        this.listeners.push({
            element: element,
            event: event,
            handler: handler
        });
        Event.observe(element, event, handler);
    },

    unregisterListener: function(element, event, handler) {
        var newListeners = [];
        for (var i=0;i<this.listeners.length;i++) {
            if (this.listeners[i] == {element: element, event: event, handler: handler}) {
                Event.stopObserving(this.listeners[i].element, this.listeners[i].event, this.listeners[i].handler);
            } else {
                newListeners.push(this.listeners[i]);
            }
        }
        this.listeners = newListeners;

        return true;
    },

    unregisterListeners: function() {
        for (var i=0;i<this.listeners.length;i++) {
            Event.stopObserving(this.listeners[i].element, this.listeners[i].event, this.listeners[i].handler);
        }
        this.listeners = [];
	}

};
