var collection = new Class({
	Implements: [Chain, Events, Options],

	options: {
		imagesDirectory: 'assets/images/content/collection/',
		thumbnailsDirectory: 'assets/images/content/collection/thumbnails/'
	},

  initialize: function(data, options) {
		this.setOptions(options);
		this.productCollection = { 'productNrs': [], 'images': [], 'details': [] }
		this._busy = false;
		this._freshPage = true;
		this._currentProduct = 0;
		this._currentProductImage = 0;
		this._currentHeading = '';
		this.timer = null;

    this.gridContainer = document.id('containerGrid');
    this.gridElementsContainer = new Element('div', { 'class': 'grid' }).inject(this.gridContainer);
    this.clearGrid();

		this.productDetailsContainer = document.id('containerProductDetails');
		this.clearProductDetails();

		mySite.addEvent('gridElementsCreated', this.animateGrid.bind(this));

		this.bound = {
      gridElementClicked: this.gridElementClicked.bindWithEvent(this),
      viewLargeImage: this.viewLargeImage.bind(this)
		};

    //Required elements
    var productInfo = (document.id('productInfo')) ? productInfo.empty() : new Element('div', { id: 'productInfo' });
	  var productImages = new Element('div', { id: 'productInfoImagesContainer' });
	  var productDetails = new Element('div', { id: 'productInfoDetails' });
	  productInfo.adopt(productImages, productDetails);
	  this.productDetailsContainer.grab(productInfo);
		this.productImages = document.id('productInfoImagesContainer');
		this.productInfoDetails = document.id('productInfoDetails');

		if($defined(data) && data !== null) this.buildGrid(data);
		  else this.setupNavigation();
			//else this.loadData('collection/summer/kids/all/1');
  },

	showProtectionSheet: function() {
		//console.log('showProtectionSheet');
		var coordinates = this.gridContainer.getCoordinates();
		var protectionSheet = new Element('div', {
			id: 'protectionSheet',
			styles: {
				top: coordinates.top,
				left: coordinates.left,
				width: coordinates.width,
				height: coordinates.height
			},
			events: {
				click: function(e) {
					e.stop();
					//console.log('protectionSheet');
				}
			}
		}).set('opacity', 0.1).inject(document.id('containerPages'), 'before');
	},

	removeProtectionSheet: function() {
		//console.log('removeProtectionSheet');
		document.id('protectionSheet').destroy();
	},

  setupNavigation: function() {
    new Request.JSON({
			url: 'assets/handlers/handler.collection.menu.php',
			onSuccess: function(response) {
				if(response.result == 'success') {
					this.navigation = new dropDownNavigation(response.data, {
						container: 'containerCollectionNavigation'
					});
					this.navigation.addEvent('linkClicked', function(filter) {
    				this.navigation.hide();
    				this.clearGrid();
						this.destroyProduct();
    				this.loadData(filter);
					}.bind(this));
				}
			}.bind(this)
		}).send();
  },

  refreshHeading: function(text) {
    var test = document.id(this.gridHeading);
    if(test) this.gridHeading.fireEvent('update', text);
      else this.buildHeading(text);
  },

  buildHeading: function(text) {
    this.gridHeading = new Element('div', {
      'class': 'heading'
    }).store('originalText', text).inject(this.gridContainer, 'top');
    new Element('h3').set('text', text).inject(this.gridHeading).fade('in');
    this.attachHeading();
  },

  headingSwitchNavigation: function() {
    var _self = this;
    this.navigation.show();
		new IdleTimer('containerCollectionNavigation', {
  	  timeout: 3000,
  	  events: ['mouseenter', 'mousemove', 'mousedown', 'mouseup']
  	}).addEvents({
      idle: function() {
        this.stop();
        _self.navigation.hide();
        _self.fadeGrid('in').fadeProduct('in');
        _self.flipHeading(_self.gridHeading);
        _self.gridHeading.fade('in');
      },
      active: function() {}
  	}).start();    
  },

  flipHeading: function(element, to) {
    if(!$defined(to)) to = 'heading';
    if(to == 'heading') {
		  element.removeClass('alt');
		  element.getElement('h3').set('text', element.retrieve('originalText'));
	  } else if(to == 'link') {
			element.addClass('alt');
			element.getElement('h3').set('html', '/ <span class="underline">Make a new selection</a>');
	  }
    return this;
  },

	attachHeading: function() {
	  var _self = this;
		this.gridHeading.addEvents({
			mouseenter: function() {
			  $clear(_self.headingTimer);
			  if(this.hasClass('alt')) return;
        _self.flipHeading(this, 'link');
			},
			mouseleave: function() {
			  $clear(_self.headingTimer);
			  var fn = function() {
			    _self.flipHeading(this);
			  }.bind(this);
			  _self.headingTimer = fn.delay(400, this);
			},
			click: function() {
			  if(this._busy) return;
			  _self.fadeGrid().fadeProduct();
        tween = this.get('tween');
        tween.start('opacity', 0).chain(function() { _self.headingSwitchNavigation(); });
			},
			update: function(text) {
			  this.getElement('h3').set('text', text);
			  this.store('originalText', text).fade('in');
			}
		});
	},

  loadData: function(filter) {
    new Request.JSON({
			url: 'assets/handlers/handler.collection.php',
			data: {
				filter: filter
			},
			onRequest: function() {
				//RESET
				this._currentProduct = 0;
				this.productCollection = { 'productNrs': [], 'images': [], 'details': [] }
			}.bind(this),
			onSuccess: function(response) {
				if(response.result == 'success') {
				  (function() {
				    this._busy = true;
						this._freshPage = true;
  				  if(response.data.heading) {
  				    var heading = response.data.heading
    				  if(this._currentHeading != heading) {
    				    this._currentHeading = heading;
                this.refreshHeading(heading);
    				  } else if(this.gridHeading.get('opacity') < 1) {
    				    this.gridHeading.fade('in');
    				  }
  				  }
						//Start
  					this.buildGrid(response.data.elements);
					}.bind(this)).delay(1000);
      	}
			}.bind(this)
		}).send();
  },

  buildGrid: function(data) {
	console.log('DATA: ', data);
    newElements.initialize(data, this.gridElementsContainer, 'gridElementsCreated');
  },

  fadeGrid: function(state) {
    if(!$defined(state)) state = 'out';
		this.gridElementsContainer.fade(state);
    return this;
  },

  clearGrid: function() {
    var grid = this.gridElementsContainer;
		if(grid.get('opacity') == 0) {
			grid.empty().set('opacity', 1);
		} else {
			if(Browser.Engine.trident) {
				var images = this.gridElementsContainer.getElements('img');
				images.fade('out');
				(function(){
					grid.empty().set('opacity', 1);
				}.bind(this)).delay(300);
			} else {
				grid.fade('out').get('tween').chain(function() {
		      grid.empty().set('opacity', 1);
				}.bind(this));
			}
		}
		return this;
  },

  animateGrid: function() {
    var elements = this.gridElementsContainer.getChildren();
		var myChainsObserver = new chainsObserver();
		myChainsObserver.addEvent('chainsCompleted', function() {
			this.cleanNewElements();
			this.gridElementsContainer.getElements('.item').setStyles({
				'background-color': 'transparent',
				display: 'block',
				opacity: 1
			});
		  this.gridToSlideshow();
		}.bind(this));

		elements.each(function(item) {
		  var asset = item.getElement('.asset');
		  if(asset) {
			  var myAssetChain = new assetChain(asset);
			  item.store('startup', myAssetChain);
			  myChainsObserver.add(myAssetChain);
			}
		});

    var elementsChain = new Hash({
			elements: {
			  content: elements
			}
		});
		var chain = new Chains(elementsChain);
		myChainsObserver.add(chain);

		chain.startup();
  },

	cleanNewElements: function() {
		return this;
		var items = this.gridElementsContainer.getElements('.item');
		var assets = this.gridElementsContainer.getElements('.asset');
		assets.each(function(asset) {
			this.gridElementsContainer.inject(asset, 'top');
			asset.addClass('fixed');
		}.bind(this));
		items.destroy();
	},

  gridToSlideshow: function() {
    //console.log('gridToSlideshow');

    var assets = this.gridElementsContainer.getElements('.asset');
		assets.each(function(asset, i) {
			this.productCollection.productNrs[i] = asset.getElement('a').retrieve('href').split('/').getLast();
			//var image = asset.retrieve('original');
      //this.productCollection.images[i] = image;
    }.bind(this));

    this.slideshowGrid = new thumbnailGrid.ForSlideShow(this.gridElementsContainer, {
			slideshowWrapper: 'containerPages',
			slideshowContainerId: 'slideshowContainer'
		}).addEvents({
      processThumbnail: function() { /*console.log('processThumbnail', arguments);*/ },
      processCollectionComplete: function() { /*console.log('processCollectionComplete');*/ },
      click: this.gridElementClicked.bind(this),
      viewSlide: this.viewProduct.bind(this),
      showComplete: this.setupProductExtras.bind(this)
    });

		//move to thumbnailGrid.ForSlideShow...!?
		this.gridElementsContainer.getElements('.previousNext a').each(function(btn) {
			btn.addEvent('click', function(e) {
				e.stop();
				if(this._busy) return;
				this.gridRefresh(btn.get('href'));
			}.bind(this));
		}.bind(this));
  },

  gridElementClicked: function(index) {
    console.log('gridElementClicked: ', index);
    this._currentProduct = index;
  },

  viewProduct: function() {
		this._busy = true;
		this.showProtectionSheet();
    this.chain(
			function() {
			  if(!this._freshPage && this.slideshowProductImagesGrid && this.slideshowProductImagesGrid.slideshow && this.slideshowProductImagesGrid.slideshow.slides.length > 0) this.resetProductImages();
					else this.callChain();
			}.bind(this),

			function() {
			  if(!this._freshPage && this.slideshowGrid.slideshow && this.slideshowGrid.slideshow.slides.length > 0) this.hideProductExtras();
          else this.callChain();
			}.bind(this),

			function() {
		  	if(this.productCollection.details[this._currentProduct]) this.viewLargeImage();
			  	else this.loadProduct();
			}.bind(this)
		);
		this.callChain();
  },

  viewLargeImage: function() {
    //console.log('viewLargeImage');

		var container = document.id('slideshowContainer');
		if(container.get('opacity') === 0) {
      container.fade('in').get('tween').chain(function() {
        this.setupProductExtras();
      }.bind(this));
    } else {
  		var currentSlide = this.slideshowGrid.slideshow.slides.indexOf(this.slideshowGrid.slideshow.current);
  		var transition = (currentSlide < this.slideshowGrid.current) ? 'pushUpFunkyFade' : 'pushDownFunkyFade';
  		this.slideshowGrid.slideshow.show(this.slideshowGrid.current, {
  			transition: transition,
  			duration: 1200
  		});
    }
  },

  clearProductDetails: function() {
    this.productDetailsContainer.empty().set('opacity', 1);
  },

	setupProductExtras: function() {
		//console.log('setupProductExtras');
		this.productImages.empty().setStyle('top', 0); //reset top x-pos
		this.productInfoDetails.set('html', '<span class="left">'+this.productCollection.details[this._currentProduct].name+' / '+this.productCollection.details[this._currentProduct].productNr+'</span><span class="right">'+this.productCollection.details[this._currentProduct].flavour+'</span>');

		var images = this.productCollection.details[this._currentProduct].images;
		if(images.length > 1) {
			if(images.length > 2) this.productImages.setStyle('top', -1 * (images.length-2) * 86); //Change top x-pos
			$each(images, function(image, index) {
				var asset = new Element('div', { 'class': 'asset' });
				var configuration = {
					styles: {opacity: 0},fx: {duration: 700,transition: 'quint:out'},morph: {opacity: 1},
					original: this.options.imagesDirectory+images[index],
					href: ((index === 0) ? 'front' : 'back')+'.html',
					image: this.options.thumbnailsDirectory+images[index],
					alt: 'view '+(index === 0 ? 'front' : 'back')
				}
				asset.store('configuration', configuration);
				var item = new Element('div', { 'class': 'item' }).grab(asset);
				this.productImages.grab(item);
			}.bind(this));
    }

		this.showProductExtras();
	},

	gridRefresh: function(filter) {
		//console.log('gridRefresh');
		this.showProtectionSheet();
    this.chain(
			function() {
			  if(this.slideshowProductImagesGrid && this.slideshowProductImagesGrid.slideshow.slides.length > 0) this.resetProductImages();
          else this.callChain();
			}.bind(this),

			function() {
			  if(this.slideshowGrid.slideshow && this.slideshowGrid.slideshow.slides.length > 0) this.hideProductExtras();
          else this.callChain();
			}.bind(this),

			function() {
				var slideshowContainer = document.id('slideshowContainer');
				if(slideshowContainer) {
					slideshowContainer.fade('out').get('tween').chain(function() {
						slideshowContainer.empty();
					});
				}
				this.callChain();
			}.bind(this),

			function() {
			  this.clearGrid();
				this.removeProtectionSheet();
			  this.loadData.delay(700, this, filter);
			}.bind(this)
		);
		this.callChain();
	},

  productImagesGridToSlideshow: function() {
    //console.log('extraImagesGridToSlideshow');

    var assets = this.productImages.getElements('.asset');
    if(assets.length <= 1) {
      this._busy = false;
			this._freshPage = false;
			this.removeProtectionSheet();
      return this;
    }
		this._currentProductImage = 0;
		this.setActiveProductImage();

    this.slideshowProductImagesGrid = new thumbnailGrid.ForSlideShow(this.productImages, {
			slideshowWrapper: 'containerPages',
			slideshowContainerId: 'slideshowAltContainer'
		}).addEvents({
      processThumbnail: function() { /*console.log('productImages-processThumbnail', arguments);*/ },
      processCollectionComplete: function() {
				//console.log('productImages-processCollectionComplete');
				document.id('slideshowAltContainer').set('opacity', 1);
			}.bind(this),
      click: function(index) {
				this._currentProductImage = index;
				this.setActiveProductImage();
			}.bind(this),
      viewSlide: this.viewProductImage.bind(this),
      showComplete: function() { /*console.log('productImages-showComplete');*/ }
    });
		this.removeProtectionSheet();
  },

	viewProductImage: function() {
 		var currentIndex = this.slideshowProductImagesGrid.slideshow.slides.indexOf(this.slideshowProductImagesGrid.slideshow.current);
 		var transition = (currentIndex < this.slideshowProductImagesGrid.current) ? 'pushRightFunky' : 'pushLeftFunky';
 		this.slideshowProductImagesGrid.slideshow.show(this.slideshowProductImagesGrid.current, {
 			transition: transition,
 			duration: 700
 		});
	},

	setActiveProductImage: function() {
		var assets = this.productImages.getElements('.asset');
		var asset = assets[this._currentProductImage];

		var activeProductImageIndicator = document.id('activeProductImageIndicator');
		if(!activeProductImageIndicator) {
			var activeProductImageIndicator = new Element('div', {
				id: 'activeProductImageIndicator',
				styles: {
					height: asset.getSize().y
				}
			});
			this.productImages.grab(activeProductImageIndicator, 'top');
		}
		activeProductImageIndicator.set('tween', {
			duration: 300
		});
		activeProductImageIndicator.position({
			relativeTo: asset,
			position: 'topLeft',
			offset: { x: -11, y: 0 }
		}).set('opacity', 0).fade('in').get('tween').chain(function() {
  		this._busy = false;
			this._freshPage = false;
		}.bind(this));
	},

	resetProductImages: function() {
		//console.log('resetProductImages');
		var delay = 50;
		var assets = this.productImages.getElements('.asset');
 		var currentIndex = this._currentProductImage;
		//console.log('alt images currentIndex: ', currentIndex);
		if(currentIndex !== 0) {
			this._currentProductImage = 0;
			delay = 400;
			this.setActiveProductImage();
  		var transition = (currentIndex < 0) ? 'pushRightFunky' : 'pushLeftFunky';
  		this.slideshowProductImagesGrid.slideshow.show(0, {
  			transition: transition,
  			duration: 600
  		});
		}
		(function() {
			this.slideshowProductImagesGrid = null;
			$('slideshowAltContainer').destroy();
			this.callChain();
		}.bind(this)).delay(delay);
	},

	destroyProduct: function() {
		var container = document.id('slideshowAltContainer');
		if(container) {
			this.slideshowProductImagesGrid = null;
			container.destroy();
		}
		this.productImages.empty();

		this.productInfoDetails.empty();
		container = document.id('slideshowContainer');
		if(container) {
			this.slideshowGrid = null;
			container.destroy();
		}
		return this;
	},

	showProductExtras: function() {
		//console.log('showProductExtras');
	  this._busy = true;
		var nrOfImages = this.productCollection.details[this._currentProduct].images.length;

		this.productInfoDetails.store('configuration', {styles:{opacity:0},fx:{duration:400,transition:'back:out'},morph:{opacity:1,height:[0,30],marginTop:[207,177]}});
		this.productInfoDetails.getChildren('span').store('configuration', {styles:{opacity:0},fx:{duration:200},morph:{opacity:1}});

		var myChainsObserver = new chainsObserver();
		myChainsObserver.addEvent('chainsCompleted', this.productImagesGridToSlideshow.bind(this));

		var elementsChain = new Hash({
			infoContainer: {
				content: [this.productInfoDetails]
			},
			info: {
				content: this.productInfoDetails.getChildren('span')
			}
		});
		if(nrOfImages > 1) {
			var imageElements = this.productImages.getChildren();
			imageElements.store('configuration', {styles:{opacity:0},fx:{duration:200,transition:'back:out'},morph:{opacity:1,marginLeft:[80,0],width:[0,80]}});

			imageElements.each(function(item) {
				var asset = item.getElement('.asset');
				if(asset) {
					var myAssetChain = new assetChain(asset);
					item.store('startup', myAssetChain);
					myChainsObserver.add(myAssetChain);
				}
			});

		  elementsChain.extend({
				images: {
					content: imageElements
				}
		  });
		}
		var chain = new Chains(elementsChain);
		myChainsObserver.add(chain);
	
		chain.startup();
	},

  fadeProduct: function(state) {
    if(!$defined(state)) state = 'out';
    document.id('containerProductDetails').fade(state);
    document.id('slideshowContainer').fade(state);
    if(document.id('slideshowAltContainer')) document.id('slideshowAltContainer').fade(state);
    return this;
  },

	hideProductExtras: function() {
	  this._busy = true;
	  if(!this.productInfoDetails) return this;
		//console.log('hideProductExtras');
		var imageItems = this.productImages.getChildren('.item');

		this.productInfoDetails.store('configuration', {styles:{opacity:1},fx:{duration:400,transition:'back:in'},morph:{opacity:0,height:[30,0]}});
		this.productInfoDetails.getChildren('span').store('configuration', {styles:{opacity:1},fx:{duration:200},morph:{opacity:0}});

		var myChainsObserver = new chainsObserver();
		var delay = 600 + 300 + ((imageItems.length * 300)*0.9);
		myChainsObserver.addEvent('chainsCompleted', function() {
		  (function() {
		    this.callChain();
		  }.bind(this)).delay(delay);
		}.bind(this));

		var elementsChain = new Hash({});

		if(imageItems.length > 1) {
			document.id('activeProductImageIndicator').store('configuration', {styles:{opacity:1},fx:{duration:300},morph:{opacity:0}});
			imageItems.store('configuration', {styles:{opacity:1},fx:{duration:300,transition:'back:in'},morph:{opacity:0,marginLeft:[0,80],width:[80,0]}});
			elementsChain.extend({
				indicator: {
					content: [document.id('activeProductImageIndicator')]
				},
				items: {
					content: imageItems
				}
			});
		}

		elementsChain.extend({
			info: {
				content: this.productInfoDetails.getChildren('span')
			},
			infoContainer: {
				content: [this.productInfoDetails]
			}
		});

		var chain = new Chains(elementsChain);
		myChainsObserver.add(chain);

		chain.startup();
	},

  loadProduct: function() {
    new Request.JSON({
			url: 'assets/handlers/handler.product.php',
      data: {
        productId: this.productCollection.productNrs[this._currentProduct]
      },
      onSuccess: function(response) {
        if(response.result == 'success') {
					this.viewLargeImage();
					this.productCollection.details[this._currentProduct] = response.data;
				}
      }.bind(this)
    }).send();
  }
});

//moo 1.2 doesn't match data- attributes, 1.3 does, however
Selectors.RegExps.combined = (/\.([\w-]+)|\[([\w-]+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g);

