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 = { 'images': [], 'details': [] }
		this._busy = false;
		this._currentProduct = 0;
		this._currentHeading = '';

    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.slideshow = new SlideshowCurrent(this.productDetailsContainer, [], {
			transition: 'back:in:out',
			resize: 'length',
			center: false,
			width: 1200,
			height: 1200,
			imageWidth: 450,
			imageHeight: 450,
			autoShow: false,
			slide: this._currentProduct
		});
		this.slideshow.addEvent('slideMoved', this.setProductDetails.bind(this));

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

  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.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();
  },

	attachHeading: function() {
	  var _self = this;
		this.gridHeading.addEvents({
			mouseenter: function() {
			  $clear(_self.headingTimer);
			  if(this.hasClass('alt')) return;
				this.addClass('alt');
				this.getElement('h3').set('html', '/ <span class="underline">Make a new selection</a>');
			},
			mouseleave: function() {
			  $clear(_self.headingTimer);
			  var fn = function() {
  				this.removeClass('alt');
  				this.getElement('h3').set('text', this.retrieve('originalText'));
			  }.bind(this);
			  _self.headingTimer = fn.delay(400, this);
			},
			click: function() {
			  if(this._busy) return;
			  var fn = function() {
			    this.navigation.show();
			  }.bind(this)
				if(Browser.Engine.trident) this.gridElementsContainer.empty();
			  	else this.gridElementsContainer.fade('out');
			  this.gridHeading.fade('out').retrieve('tween').chain(fn);
			}.bind(this),
			update: function(text) {
			  this.getElement('h3').set('text', text);
			  this.store('originalText', text).fade('in');
			}
		});
	},

  loadData: function(filter) {
    new Request.JSON({
			//url: 'loaddata.php',
			url: 'assets/handlers/handler.collection.php',
			data: {
				filter: filter
			},
			onRequest: function() {
				this.navigation.hide();
			  this.clearGrid();
			}.bind(this),
			onSuccess: function(response) {
				if(response.result == 'success') {
				  (function() {
				    this._busy = 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');
    				  }
  				  }
  					this.buildGrid(response.data.elements);
					}.bind(this)).delay(1000);
      	}
			}.bind(this)
		}).send();
  },

  clearGrid: function() {
		this.gridElementsContainer.empty().set('opacity', 1);
  },

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

  animateGrid: function() {
    var elements = this.gridElementsContainer.getChildren();

		var myChainsObserver = new chainsObserver();
		myChainsObserver.addEvent('chainsCompleted', function() {
		  this.processGrid();
		  this.initProductDetails();
		}.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();
  },

  processGrid: function() {
		//TEMP
		this.ssSetup();

    var gridElements = this.gridElementsContainer.getElements('.asset');
		gridElements.each(function(asset, i) {
			//TEMP
			this.ssCreateSlide(asset);

      var index = this.productCollection.images.indexOf(asset.retrieve('original'));
      if(index == -1) {
        index = this.productCollection.images.length;
        this.productCollection.images[index] = asset.retrieve('original');
        this.slideshow.add(asset.retrieve('original'), index); //instead of loading batch, which is buggy
      }
			if(i === 0) this._currentProduct = index;
			asset.store('index', index);
      this.attachGridElement(asset);
    }.bind(this));

		this.gridElementsContainer.getElements('.previousNext a').each(function(link) {
			link.addEvent('click', function(e) {
				e.stop();
				if(this._busy) return;
				var fn = function() {
          this.loadData(link.get('href'));
				}.bind(this)
				this.gridElementsContainer.fade('out').retrieve('tween').chain(fn);
			}.bind(this));
		}.bind(this));

		//TEMP
		this.ssMake();
  },

  attachGridElement: function(element, attach) {
    var method = $pick(attach, true) ? 'addEvents' : 'removeEvents';
    element[method]({
      'click': this.bound.gridElementClicked,
      'slideTo': this.bound.viewLargeImage
    });
    return this;
  },

  detachGridElement: function(element) {
    this.attachGridElement(element, false);
    return this;
  },

  gridElementClicked: function(e) {
    e.stop();
    //console.log('busy: ', this._busy);
    if(this._busy) return;
    var asset = e.target.getParent('.asset');
    var index = asset.retrieve('index');
		if(this._currentProduct === index) return this;
		this._currentProduct = index;
		this.viewProduct(asset);
  },

  viewProduct: function(asset) {
    if($defined(asset)) currentAsset = asset;
      else currentAsset = this.gridElementsContainer.getElements('.asset')[0];
    //console.log('vP asset2: ', currentAsset, currentAsset.getElement('img'), currentAsset.retrieve('index'), this._currentProduct);

    this.chain(
			function() {
			  if(this.slideshow.counter > 0) this.hideProduct();
          else this.callChain()
			}.bind(this),

			function() {
		  	if(this.productCollection.details[this._currentProduct]) currentAsset.fireEvent('slideTo');
			  	else this.loadProduct(currentAsset);
			}.bind(this)
		);
		this.callChain();
  },

  viewLargeImage: function() {
    this.slideshow.go(this._currentProduct);
  },

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

  initProductDetails: function() {
    /* Adding images to slideshow 1-by-1 in processGrid
    var imagesBatch = this.productCollection.images.slice(this._currentProduct, this.productCollection.images.length);
    this.slideshow.load(imagesBatch); */
    this.viewProduct();
  },

	setProductDetails: function() {
		this.productImages.empty().setStyle('top', 0);
		document.id('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) {
			//Change top x-pos
			if(images.length > 2) this.productImages.setStyle('top', -1 * (images.length-2) * 86);
			$each(images, function(image, index) {
				var asset = new Element('div', { 'class': 'asset' });
				if(Browser.Engine.presto) {
					//Explorer (now temps presto because it seems to work after fixing issues)
					var configuration = {
						original: this.options.imagesDirectory+images[index]
					}
					new Element('img', {
						src: this.options.thumbnailsDirectory+images[index]
					}).inject(asset);
					asset.setStyle('display', 'none');
				} else {
					//Non sucking browsers
					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.showProduct();
	},

  setupAlternateImages: function() {
    var assets = this.productImages.getElements('.asset');
    if(assets.length === 0) this._busy = false;
    var bigImage = this.slideshow.image;
    assets.each(function(asset, i) {
      asset.addEvent('click', function(e) {
        e.stop();
        bigImage.set('src', asset.retrieve('configuration').original);
				this.setActiveProductImage(asset);
      }.bind(this));
			if(i === 0) this.setActiveProductImage(asset);
    }.bind(this));
  },

	setActiveProductImage: function(asset) {
		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;
		}.bind(this));
		//TEMP
		//this.ss();
	},

	showProduct: function() {
	  this._busy = true;
		var nrOfImages = this.productCollection.details[this._currentProduct].images.length;

		if(Browser.Engine.presto) {
			//Explorer (now presto because it seems to work after all, keep it here in case of)
			document.id('productInfoDetails').set('opacity', 1).show();
			document.id('productInfoDetails').getChildren('span').set('opacity', 1).show();
			if(nrOfImages > 1) {
				var imageElements = this.productImages.getChildren();
				$each(imageElements, function(element) {
					element.show().getElement('.asset').set('opacity', 1).show();
				});
			}
			this.setupAlternateImages();
		} else {
			//Non sucking browsers
			document.id('productInfoDetails').store('configuration', {styles:{opacity:0},fx:{duration:400,transition:'back:out'},morph:{opacity:1,height:[0,30],marginTop:[207,177]}});
			document.id('productInfoDetails').getChildren('span').store('configuration', {styles:{opacity:0},fx:{duration:200},morph:{opacity:1}});
	
			var myChainsObserver = new chainsObserver();
			myChainsObserver.addEvent('chainsCompleted', this.setupAlternateImages.bind(this));
	
			var elementsChain = new Hash({
				infoContainer: {
					content: [document.id('productInfoDetails')]
				},
				info: {
					content: document.id('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();
		}
	},

	hideProduct: function() {
	  this._busy = true;
	  if(!document.id('productInfoDetails')) return this;

		var imageItems = this.productImages.getChildren('.item');
		if(Browser.Engine.presto) {
			//Explorer, now presto check for temps, seems to work after all, keep in case of
			if(imageItems.length > 1) {
				document.id('activeProductImageIndicator').hide();
				imageItems.hide();
			}
			document.id('productInfoDetails').hide();
	    this.callChain();
		} else {
			//Non sucking browsers
			document.id('productInfoDetails').store('configuration', {styles:{opacity:1},fx:{duration:400,transition:'back:in'},morph:{opacity:0,height:[30,0],marginTop:[177,207]}});
			document.id('productInfoDetails').getChildren('span').store('configuration', {styles:{opacity:1},fx:{duration:200},morph:{opacity:0}});

			var myChainsObserver = new chainsObserver();
			myChainsObserver.addEvent('chainsCompleted', function() {
			  (function() {
			    this.callChain();
			  }.bind(this)).delay(1300);
			}.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: document.id('productInfoDetails').getChildren('span')
				},
				infoContainer: {
					content: [document.id('productInfoDetails')]
				}
			});

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

			chain.startup();
		}
	},

  loadProduct: function(asset) {
    //var productId = asset.getElement('a').get('href').split('/').getLast();
    var productId = asset.getElement('a').retrieve('href').split('/').getLast();
    new Request.JSON({
			url: 'assets/handlers/handler.product.php',
      data: {
        productId: productId
      },
      onSuccess: function(response) {
        if(response.result == 'success') {
          asset.fireEvent('slideTo');
					this.productCollection.details[this._currentProduct] = response.data;
					//Preload large product images that are not loaded by slideshow
					var images = response.data.images;
					if(images.length > 1) {
						$each(images, function(image, index) {
							if(index > 0) {
								new Asset.image(this.options.imagesDirectory+images[index], {
									onload: function() {
										//console.log('image preloaded: ', this);
									}
								});
							}
						}.bind(this));
					}
				}
      }.bind(this)
    }).send();
  },

  //TEMP
	ssMake: function() {
    var mySlideShow = new SlideShow('ssContainer'); 
    var slideLabels = document.id('containerGrid').getElements('.asset');
		console.log('s: ', slideLabels);
    slideLabels.each(function(el, index) { 
      el.store('slide', mySlideShow.slides[index]); 

      el.addEvent('mouseenter',function() {
				var currentIndex = mySlideShow.slides.indexOf(mySlideShow.current);
				var transition = (currentIndex < index) ? 'pushUpFunkyFade' : 'pushDownFunkyFade';
				mySlideShow.show(index, {
					transition: transition,
					duration: 1200
				});
        //mySlideShow.show(el.retrieve('slide')); 
      }); 

    });
	},

	ssCreateSlide: function(asset) {
		var file = asset.retrieve('original');
		var img = new Element('img', {
			src: file,
			width: 450,
			height: 450
		});
		var slide = new Element('div', {
			class: 'slide',
			styles: {
				marginTop: 100,
				width: 450,
				height: 450
			}
		}).adopt(img);
		//slide.addClass('transition:pushUp duration:1200');
		document.id('ssContainer').grab(slide);
	},

	ssSetup: function() {
    var ssContainer = new Element('div', {
      id: 'ssContainer',
      styles: {
        width: 450,
        height: '100%',
        overflow: 'hidden',
        position: 'absolute',
        left: 1000,
        zIndez: 99999,
        backgroundColor: 'transparent'
      }
    });
		document.id('containerPages').grab(ssContainer, 'top');
		//Add fx
		SlideShow.add('pushUpFunky', function(previous, next, duration, instance) {
			var distance = instance.element.getSize().y;
			next.setStyle('top', distance);
			new Fx.Elements([previous, next], {
				duration: duration,
				transition: 'back:in:out'
			}).start({
				0: { top: [-distance] },
				1: { top: [0] }
			});
			return this;
		});
		SlideShow.add('pushDownFunky', function(previous, next, duration, instance) {
			var distance = instance.element.getSize().y;
			next.setStyle('top', -distance);
			new Fx.Elements([previous, next], {
				duration: duration,
				transition: 'back:in:out'
			}).start({
				0: { top: [distance] },
				1: { top: [0] }
			});
			return this;
		});

		SlideShow.add('pushUpFunkyFade', function(p,n,d,i) {
			this.pushUpFunky(p,n,d,i).fade(p,n,d,i);
		});
		SlideShow.add('pushDownFunkyFade', function(p,n,d,i) {
			this.pushDownFunky(p,n,d,i).fade(p,n,d,i);
		});
	},

  ss: function() {
    var container = new Element('div', {
      id: 'ss',
      styles: {
        width: 450,
        height: 450,
        overflow: 'hidden',
        position: 'absolute',
        left: 1000,
        top: 100,
        zIndez: 99999,
        backgroundColor: 'green'
      }
    });
    var assets = this.productImages.getElements('.asset');
    $each(assets, function(asset) {
      var src = asset.getElement('img').get('src');
      var file = src.split('/').getLast();
      var img = new Element('img', {
        src: this.options.imagesDirectory+file,
        width: 450,
        height: 450
      });
      var slide = new Element('div', {
        class: 'slide',
        styles: {
          width: 450,
          height: 450
        }
      }).adopt(img);
      slide.addClass('transition:crossFade duration:300');
      container.adopt(slide);
    }.bind(this));
    document.id('containerPages').grab(container);

    mySlideShow = new SlideShow('ss'); 
    var slideLabels = assets;
    slideLabels.each(function(el, index) { 
      el.store('slide', mySlideShow.slides[index]); 

      el.addEvent('mouseenter',function() {
        mySlideShow.show(el.retrieve('slide')); 
      }); 

    });
  }
});