/*
---

name: Collection

description: Fx and glue for several things...

authors: Rolf Langenhuijzen

license: MIT-style license.

requires: [Core, HTMLElements, Chains, ChainsObserver, DropDownNavigation, IdleTimer, PowerTools!/History]

provides: Collection

...
*/

var Collection = new Class({

	Implements: [Events, Options, Chain],

	options: {
		imagesDirectory: 'assets/images/',
		thumbnailsDirectory: 'assets/images/thumbnails/',
		initialIndex: 0
	},

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

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

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

    //Required elements
    var productInfo = (document.id('productInfo')) ? productInfo.empty() : new Element('div', { id: 'productInfo' }),
			productImages = new Element('div', { id: 'productInfoImagesContainer' }),
			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 (data != null){
			if (typeof(data) == 'string') History.push(data);
				else if (typeof(data) == 'object') this.processData(data);
		} else {
			throw new Error('Error: no data...');
		}
  },

  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();

		new FitText(this.gridHeading,'h3', {
			fitClass: 'fittext'
		});
  },

  headingSwitchNavigation: function(){
		History.push('/collections/');
		//console.log('FIX headingSwitchNavigation');
		/*
		this.setupNavigation();
    var _self = this;
		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(to == null) 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(){
				clearTimeout(_self.headingTimer);
			  if (this.hasClass('alt')) return;
        _self.flipHeading(this, 'link');
			},
			mouseleave: function(){
			  clearTimeout(_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');
			}
		});
	},

	processData: function(data){
		//console.log('processData: ', data);
	  (function(){
	    this._busy = true;
			this._freshPage = true;
			if (data.heading){
				var heading = 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(data.elements);
		}.bind(this)).delay(1000);
	},

  buildGrid: function(elements){
		//console.log('buildGrid: ', this.gridElementsContainer, elements);
		new HTMLElements({
			data: elements,
			parentContainer: this.gridElementsContainer,
			onElementsCreated: this.animateGrid.bind(this)
		});
  },

  animateGrid: function(){
		//console.log('animateGrid');
    var elements = this.gridElementsContainer.getChildren(),
			myChainsObserver = new ChainsObserver();
		myChainsObserver.addEvent('chainsCompleted', function(){
			//Clean up; fixes sometimes flaws when changing grid and you keep seeing the dark backgrounds
			this.gridElementsContainer.getElements('.item').setStyles({
				'background-color': 'transparent',
				display: 'block',
				opacity: 1
			});
			//Turn grid into slideshow
		  this.gridToSlideshow.delay(50, this);
			//Previous & Next in grid
			this.handlePreviousNext.delay(1900, this);
		}.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 = {
			elements: {
			  content: elements
			}
		};
		var chain = new Chains(elementsChain);
		myChainsObserver.add(chain);

		chain.startup();
  },

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

  clearGrid: function(){
		//console.log('clearGrid');
		document.id(this.gridHeading).fade('out');
    var grid = this.gridElementsContainer;
		if (grid.get('opacity') == 0){
			grid.empty().set('opacity', 1);
		} else {
			if (Browser.ie){
				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;
  },

	handlePreviousNext: function(){
		//Should use event delegation...
		this.gridElementsContainer.getElements('.previousNext a').each(function(btn){
			btn.fade('in').addEvent('click', function(event) {
				event.preventDefault();
				if (this._busy) return;
				this.gridRefresh(btn.get('href'));
			}.bind(this));
		}.bind(this));
		return this;
	},

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

    this.slideshowGrid = new Gallery(this.gridElementsContainer, {
			initialIndex: this.options.initialIndex,
      ThumbnailGridOptions: {
        thumbnailContainerSelector: '.asset'
      },
      slideshowWrapper: 'containerPages',
      slideshowContainerId: 'slideshowContainer',
      showSlideOnClick: false,
      SlideShowOptions: {
				imageAsBackground: (Browser.ie7 || Browser.ie8) ? false : true
			},
      onSetupSlideShow: function(){
        document.id('slideshowContainer').set('opacity', 0);
        this.loadProduct();
				//console.log('onSetupSlideShow: loadProduct');
      }.bind(this),
      onClick: function(event, index, clicked){
        this._currentProduct = index;
        this.loadProduct();
				newHistoryURL = clicked.getElement('a').get('href');
      }.bind(this),
      onShow: function(slideData){
        //console.log('show: ', slideData);
      },
      onShowComplete: function(slideData){
        //console.log('showComplete: ', slideData);
				if (window.History && newHistoryURL != '' && !Browser.ie6 && !Browser.ie7) History.fakePush(newHistoryURL);
				mySite.fireEvent('setDocumentTitle', this.productCollection.details[this._currentProduct].title);
        this.setupProductExtras();
      }.bind(this),
      onLoadImageComplete: function(index, options){
        this.viewProduct();
      }.bind(this)
    });

		return this;
  },

  viewProduct: function(){
		this._busy = true;
    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(){
			  this.viewLargeImage();
			}.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 s = this.slideshowGrid.slideshow
				currentSlide = s.slides.indexOf(s.current),
				transition = (currentSlide < this._currentProduct) ? 'pushUpFunkyFade' : 'pushDownFunkyFade';
			s.show(this._currentProduct, {
        transition: transition,
        duration: 1200
			});
			
    }
  },

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

	setupProductExtras: function(){
		//console.log('setupProductExtras');
		if (!this.showProductExtrasFlag || !this.productCollection.details[this._currentProduct]){
		  //console.log('product extras not available');
		  this._busy = false;
		  return this;
		}

		this.productImages.empty().setStyle('top', 0); //Reset top x-pos
    this.productImages.removeEvents(); //Temporary because of event delegation in ThumbnailGrid....FIX needed!
		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
			images.each(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',*/
					href: 'javascript:void(0);',
					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){
    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();
				History.push.delay(800, History, filter);
			}.bind(this)
		);
		this.callChain();
	},

  productImagesGridToSlideshow: function(){
    //console.log('productImagesGridToSlideshow');
    var assets = this.productImages.getElements('.asset');
    if (assets.length <= 1){
      this._busy = false;
			this._freshPage = false;
      return this;
    }
		this._currentProductImage = 0;

		this.slideshowProductImagesGrid = new Gallery(this.productImages, {
      ThumbnailGridOptions: {
        thumbnailContainerSelector: '.asset'
      },
      slideshowWrapper: 'containerPages',
      slideshowContainerId: 'slideshowAltContainer',
      showSlideOnClick: false,
      SlideShowOptions: {},
      onClick: function(event, index){
				this._currentProductImage = index;
				this.setActiveProductImage();
      }.bind(this),
      onLoadImageComplete: function(index, options){
        this.viewProductImage();
      }.bind(this)
    });
		this.setActiveProductImage();
		this.shareBtn();
	  return this;
  },

	viewProductImage: function(){
	  var s = this.slideshowProductImagesGrid.slideshow,
			currentSlide = s.slides.indexOf(s.current);
    if (currentSlide == this._currentProductImage) return this;
		var transition = (currentSlide < this._currentProductImage) ? 'pushLeftFunky' : 'pushLeftFunky';
		s.show(this._currentProductImage, {
      transition: transition,
      duration: 700
		});
		return this;
	},

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

		if (!activeProductImageIndicator){
			var activeProductImageIndicator = new Element('div', {
				id: 'activeProductImageIndicator',
				styles: {
					height: asset.getSize().y
				}
			});
  		activeProductImageIndicator.set('tween', {
  			duration: 300
  		});
			this.productImages.grab(activeProductImageIndicator, 'top');
		}

		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,
			assets = this.productImages.getElements('.asset'),
			currentIndex = this._currentProductImage;
		//console.log('alt images currentIndex: ', currentIndex);
		if (currentIndex !== 0){
			this._currentProductImage = 0;
			delay = 1000;
			this.setActiveProductImage();
  		var transition = (currentIndex < 0) ? 'pushRightFunky' : 'pushLeftFunky';
  		this.slideshowProductImagesGrid.slideshow.show(0, {
  			transition: transition,
  			duration: 600
  		});
		}
		(function(){
			this.slideshowProductImagesGrid = null;
			document.id('slideshowAltContainer').destroy();
			this.callChain();
		}.bind(this)).delay(delay);
	},

	destroyProduct: function(){
		//console.log('destroyProduct');
		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 = {
			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);
				}
			});

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

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

	hideProductExtras: function(){
	  this._busy = true;
	  if (!this.productInfoDetails) return this;
		//console.log('hideProductExtras');
		this.shareBtn('hide');
		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 = 700 + 300 + ((imageItems.length * 300)*0.9);
		myChainsObserver.addEvent('chainsCompleted', function() {
		  (function(){
		    this.callChain();
		  }.bind(this)).delay(delay);
		}.bind(this));

		var elementsChain = {}

		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]}});
			Object.append(elementsChain, {
				indicator: {
					content: [document.id('activeProductImageIndicator')]
				},
				items: {
					content: imageItems
				}
			});
		}

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

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

		chain.startup();
	},

  sharePage: function(url){
    console.log('share: www.4funkyflavours.eu', url);
  },

  shareBtn: function(action){
		return this;
		/*
    if (action == null) action = 'show';
    if (action != 'show'){
      btn = document.id('btnShare');
      if (btn) btn.fade('out').get('tween').chain(function(){ btn.destroy(); });
    } else {
      var assets = this.productImages.getElements('.asset'),
        productData = this.productCollection.details[this._currentProduct];

      var a = new Element('a', {
        id: 'btnShare',
        text: '+ Share',
        title: 'Share & like this on Facebook, Twitter, Google+, etc.',
        href: productData.url,
        events: {
          click: function(event){
            event.preventDefault();
            this.sharePage(productData.url);
          }.bind(this)
        }
      }).inject(document.id('productInfo'), 'top');

  		a.position({
  			relativeTo: assets[0],
  			position: 'topLeft',
  			offset: { x: 0, y: -39 }
  		}).fade('in');
    }
    return this;
		*/
  },

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

});

