﻿

var PageLoader = new Class({
	Implements: [Events, Options],
	options: {
		/* onLoaded: $empty, */
		defaultTransition: 'fade',
		defaultItemDelay: 0,
		defaultAnimDelay: 300,
		defaultAnimLength: 600,
		defaultAnimOffset: 0
	},
	overrideConst: '*ANIMATIONOVERRIDE*',
	sectionImages: [],
	sectionPieces: [],
	sectionImagesLoaded: {},
	sectionImagesToLoad: {},
	sectionPiecesLoaded: {},
	sectionPiecesToLoad: {},
	sectionBackgroundImages: [],
	initialize: function (options) {
		if (options)
			this.setOptions(options);
		window.addEvent('unload', function() { return; }); //force cache purge in FF when back button is pressed
	},
	addSection: function (sectionName, selector, backgroundImages, animationOverride) {
		if (animationOverride) sectionName += this.overrideConst;
		this.sectionPieces[sectionName] = $$(selector);
		this.sectionImages[sectionName] = $$(selector).filter('img');
		$$(this.sectionPieces[sectionName]).set('opacity', 0);

		this.sectionBackgroundImages[sectionName] = [];
		this.sectionImagesLoaded[sectionName] = 0;
		this.sectionPiecesLoaded[sectionName] = 0;
		this.sectionImagesToLoad[sectionName] = this.sectionImages[sectionName].length;
		this.sectionPiecesToLoad[sectionName] = this.sectionPieces[sectionName].length;

		if (backgroundImages) {
			backgroundImages.each(function (backImg) {
				this.addSectionBackgroundImg(sectionName, backImg);
				this.sectionImagesToLoad[sectionName]++;
			}, this);
		}

		this.sectionImages[sectionName].each(function (img) {
			if (img.complete)
				this.sectionImgLoaded(img, sectionName);
			else
				img.addEvent('load', function(e) { this.sectionImgLoaded(e, sectionName); }.bind(this));
		}, this);

		if (this.sectionImages[sectionName].length == 0)
			this.animateSectionIn.delay(500, this, sectionName);
	},
	addSectionBackgroundImg: function (sectionName, backImg) {
		this.sectionBackgroundImages[sectionName].push(backImg);
		var self = this;
		new Asset.image(backImg.src, { onLoad: function(e) { this.sectionImgLoaded(e, sectionName); }.bind(this) });
	},
	sectionImgLoaded: function (e, sectionName) {
		this.sectionImagesLoaded[sectionName]++;
		if (this.sectionImagesLoaded[sectionName] == this.sectionImagesToLoad[sectionName])
			this.animateSectionIn(sectionName);
	},
	animateSectionIn: function (sectionName) {
		this.sectionBackgroundImages[sectionName].each(function (backImg) {
			$(backImg.id).setStyle('background-image', backImg.src.cssUrl());
		});
		var delay = 0;
		var fast = (sectionName.contains(this.overrideConst));
		this.sectionPieces[sectionName].each(function (piece) {
			animLength = this.options.defaultAnimLength;
			itemDelay = fast ? 0 : this.options.defaultItemDelay;
			animDelay = this.options.defaultAnimDelay;
			animOffset = this.options.defaultAnimOffset;
			loadOptions = {};
			transition = this.options.defaultTransition;
			tweenProperty = '';
			tweenFrom = -1;
			tweenTo = -1;

			if (piece.getProperty('loadOptions'))	loadOptions = eval('({' + piece.getProperty('loadOptions').convertCssStringToJson() + '})');
			if (loadOptions.animLength)				animLength = loadOptions.animLength; //todo: validate input all members
			if (loadOptions.animTransition)			transition = loadOptions.animTransition.toLowerCase();
			if (loadOptions.animDelayBefore)		animDelay = loadOptions.animDelayBefore;
			if (loadOptions.itemDelayBefore)		itemDelay = loadOptions.itemDelayBefore;
			if (loadOptions.animOffset)				animOffset = loadOptions.animOffset;

			if (transition == 'skip') {
				this.sectionPiecesLoaded[sectionName]++;
				this.itemAnimComplete();
				return;
			}

			if (fast) {
				transition = 'fade';
				delay += 50;
			} else {
				delay += animDelay;
				delay -= animOffset;
				piece.set('tween', { duration: animLength });
			}

			if (transition == 'property') {
				tweenProperty = loadOptions.animProperty;
				tweenFrom = loadOptions.animFromValue;
				tweenTo = loadOptions.animToValue;
			}

			switch (transition) {
				case 'none':
					(function () { piece.set('opacity', 1); }).delay(delay + itemDelay);
					break;
				case 'fade':
					(function (sectionName) { piece.fade('in').get('tween').chain(function() {
							this.sectionPiecesLoaded[sectionName]++;
							this.itemAnimComplete();
						}.bind(this));
					}).delay(delay + itemDelay, this, sectionName);
					break;
				case 'slideright':
				case 'slidebottom':
					if (transition.contains('right')) {
						tweenProperty = 'width';
						tweenFrom = 0;
						tweenTo = piece.getSize().x;
					} else if (transition.contains('bottom')) {
						tweenProperty = 'height';
						tweenFrom = 0;
						tweenTo = piece.getSize().y;
					}
			}

			if (tweenProperty != '' && tweenFrom != -1 && tweenTo != -1) {
				(function (sectionName, tweenProperty, tweenFrom, tweenTo) {
					piece.setStyle(tweenProperty, tweenFrom);
					piece.set('opacity', 1);
					piece.tween(tweenProperty, tweenFrom, tweenTo).get('tween').chain(function() {
						this.sectionPiecesLoaded[sectionName]++;
						this.itemAnimComplete();
					}.bind(this));
				}).delay(delay + itemDelay, this, [sectionName, tweenProperty, tweenFrom, tweenTo]);
			}

			if (loadOptions.animDelayAfter && !fast)
				delay += loadOptions.animDelayAfter;
		}, this);
	},
	itemAnimComplete: function() {
		complete = true;

		Object.each(this.sectionPiecesToLoad, function(item, index) {
			if (this.sectionPiecesLoaded[index] < this.sectionPiecesToLoad[index]) {
				complete = false;
			}
		}, this);

		if (complete)
			this.fireEvent('loaded');
	}
});


