/*
---
name: FitImage
description: fix in place and fitto screen any background image
license: MIT-style license.
authors:
  - Anton Suprun
requires:
  - Core/Array
  - Core/Class.Extras
  - Core/DOMReady
  - Core/Element.Dimensions
provides: [FitImage]
...
*/


var FitImage = new Class({

	Implements: [Events, Options],

	options: {
		'center': false,
		'minWidth': 0,
		'minHeight': 0,
		'primary': 'auto',
		'injectElement': null,
		'injectPosition': 'top',
		'offset': [460, 125]
	},
	initialize: function (element, options) {
		options = options || {};
		options.primary = options.primary && ['width', 'height', 'auto'].contains(options.primary)
			? options.primary
			: 'auto';
		this.setOptions(options);
		// *** Permanently bind some methods
		this.resize = this.resize.bind(this);
		// *** Load the image
		this.image = element;
		this.image.addEvents({'onLoad' : this._getSize()});
		// In case browser does not support load event for images
		this._getSize();
		this.attach();
	},
	attach: function () {
		window.addEvents({
			'domready': this.resize,
			'resize': this.resize
		});
	},
	detach: function () {
		window.removeEvents({
			'domready': this.resize,
			'resize': this.resize
		});
	},
	_getSize: function () {
		if (!this.size || this.size.x == 0) {
			this.size = this.image.getSize();
			this.rate = this.image.rate = this.size.x / this.size.y;
		}
		if (!this.size || this.size.x == 0) {
			return false;
		}
	},
	resize: function () {
		if (this._getSize() === false) {
			return this;
		}
		var size = window.getSize(),
			slideshowStyles = {},
			styles = {},
			offset = this.options.offset,
			third = size.x / 4,
			rate = null;
		if (third < 250) {
			offset[0] = 250 + 60;
			slideshowStyles = {left: 0};
		} else {
			offset[0] = third + 60;
			slideshowStyles = {left: third - 250, width: size.x - third - 60};
		}
		size.x = size.x - offset[0];
		size.y = size.y - offset[1];
		rate = size.x / size.y;

		// *** Set first dimension size
		if (this.options.primary == 'width' || (this.options.primary == 'auto' && this.rate > rate)) {
			styles.width  = size.x;
			styles.height = null;
		} else if (this.options.primary == 'height' || (this.options.primary == 'auto' && this.rate < rate)) {
			styles.width  = null;
			styles.height = size.y;
		} else {
			// *** Perfect fit!
			styles.width  = size.x;
			styles.height = size.y;
		}

		// *** Calculate second dimension size
		if (styles.width  === null) {styles.width = Math.round(styles.height * this.rate); }
		if (styles.height === null) {styles.height = Math.round(styles.width  / this.rate); }

		this.image.setStyles(styles);
		$('slideshow').setStyles(slideshowStyles);
		return this;
	},
	toElement: function () {
		return this.image;
	}
});
var FitSlideshow = new Class({
	Implements: [Events, Options],
	options: {
		'offset': [430, 125]
	},
	initialize: function (element, options) {
		this.element = element;
		this.resize = this.resize.bind(this);
		this.attach();
		this.resize();
	},
	attach: function () {
		window.addEvents({
			'domready': this.resize,
			'resize': this.resize
		});
	},
	detach: function () {
		window.removeEvents({
			'domready': this.resize,
			'resize': this.resize
		});
	},
	resize: function () {
		var size = window.getSize(),
			styles = {
				'width' : size.x - this.options.offset[0],
				'height' : size.y - this.options.offset[1]
			};
		this.element.setStyles(styles);
		return this;
	}
});
var Slide = new Class({
	Implements : [Events],
	initialize : function (element) {
		this.loaded = false;
		this.element = element;
		this.image = element.getElement('img');
		this.toLoad = this.image.get('src');
		this.fit = new FitImage(this.image);
	}
});
SlideShow.add('myFade', function (previous, next, duration, instance) {
	if (!next.slide.loaded) {
		next.fade('hide');
		next.slide.addEvent('onImageLoaded', SlideShow.transitions.fadeThroughBackground.pass([previous, next, duration, instance]));
	} else {
		SlideShow.transitions.fadeThroughBackground(previous, next, duration, instance);
	}
});
var Christian = new Class({
	Implements : [FitImage],
	initialize: function (Slideshow) {
		this.slideshow = Slideshow;
		new FitSlideshow($('slideshow'));
		this.images = [];
		this.slideshow.slides.each(function (el, i) {
			this.slideshow.slides[i].slide = new Slide(el);
			this.images[i] = this.slideshow.slides[i].slide.image;
		}, this);
		this.slideshow.current = this.slideshow.slides.getLast();
		this.slideshow.slides[0].setStyle('display', 'none');
		this.images.each(function (image, index) {
			image.onload = this.imageIsLoaded.pass(index, this);
			image.src = image.get('img');
		}, this);
		this.slideshow.addEvent('onShow', this.stopIfNotLoaded.bind(this));
		this.$next = $('next').addEvent('click', this.slideshow.showNext.bind(this.slideshow));
		this.$previous = $('previous').addEvent('click', this.slideshow.showPrevious.bind(this.slideshow));
	},
	imageIsLoaded : function (index) {
		if (index == 0) {
			this.slideshow.show(0);
		}
		this.slideshow.slides[index].slide.loaded = true;
		this.slideshow.slides[index].slide.fireEvent('imageLoaded');
	},
	stopIfNotLoaded : function (animation) {
		slide = animation.next.element.slide;
		slide.fit.resize();
		if (!slide.loaded) {
			animation.next.element.addEvent('onImageLoaded', this.slideshow.show.pass(animation.next.index, this));
			return false;
		}
	}
});
