// JavaScript Document
Element.implement({
	isEmpty: function(){
		switch (this.get('tag')){
			case 'input':
			  return (this.value == '');
		  break;
			case 'select':
			  return (this.selectedIndex == 0);
			break;
		}
		return null;
	}
});

var Bubble = new Class({

  initialize: function(area){
		if (!$defined(area)) return null;
		this.area = area;
		this.title = area.get('title');
		this.image = this.area.getParent('div').getElement('img');
		this.container = this.image.getOffsetParent();
		
		this.bubble = new Element('p', {
		  'class': 'bubble',
			'html' : this.title
		}).inject(this.image, 'before');
		
		// ie fix for flickering
		if (Browser.Engine.trident){
			this.bubble.setStyles({
			  'background': '#FFFFFF'
			});
		}
		
		this.bubbleFx = new Fx.Morph(this.bubble, { duration: 200, link: 'cancel', transition: Fx.Transitions.Circle });

    // calculate bubble position relative to container
		this.position = this.calculatePosition();
		this.fromStyle = {
			top: this.position.top + 20,
			left: this.position.left,
			opacity: 0
		};
		this.toStyle = $extend(this.position, { opacity: 1 });
		
		this.bubble.setStyles(this.position);
		this.bubbleFx.set(this.fromStyle);

		// remove title to prevent tooltip display in browsers
		area.removeProperty('title');
		
		// events
		this.area.addEvents({
		  'mouseenter': function(){ this.show(); }.bind(this),
			'mouseleave': function(){ this.hide(); }.bind(this)
		});
		
		return this;
		
		
	},
	
	// calculate bubble position relative to container
	// returns object with top and left coords
	calculatePosition: function(){
		var coords = this.area.get('coords');
		var imageOffset = this.image.getPosition(this.container);
		var bubbleSize = this.bubble.getSize();
		
		// calculate area center
		var coords = coords.split(',');
		var axis = { x: [], y: [] };
		coords.each(function(item, index){
		  index%2 == 0 ? axis.x.push(item.toInt()) : axis.y.push(item.toInt());
		});
		var center = {
			x: axis.x.average().toInt(),
			y: axis.y.average().toInt()
		}
		
		// calculate bubble position from bubble size, image offset and area center
		// we want it slightly up, so bubbleSize.y is ok
		var position = {
			left: imageOffset.x + center.x - (bubbleSize.x/2).toInt(),
			top: imageOffset.y + center.y - (bubbleSize.y*1.5).toInt()
		}
		
		return position;
	},
	
	show: function(){
		this.bubbleFx.start(this.toStyle);
	},
	
	hide: function(){
		this.bubbleFx.start(this.fromStyle);
	}

});

var ProductImage = new Class({

  Implements: [Events, Options],
	
	options: {
		onShow: $empty(),
		onHide: $empty(),
		onStart: $empty(),
		onComplete: $empty()
	},
	
  initialize: function(imageUrl, container){
		if (!$defined(imageUrl)) return null;
		
		this.imageUrl = imageUrl;
		this.image = null;
		this.imageLoaded = false;
		
		this.container = $(container);
		this.element = null;

		this.addEvents({
		  'start': function() { this.build(); },
			'build': function() { this.load(); }
		});
		
		this.fireEvent('start');
		return this;
	},

	load: function(){
		this.image = new Asset.image(this.imageUrl, { onLoad: this.ready() });
	},
	
	build: function(){
		this.element = new Element('div');
		this.fx = new Fx.Tween(this.element, { property: 'opacity', duration: 500, link: 'cancel'});
		this.fx.set(0);
		this.element.inject(this.container);
		this.fireEvent('build');
	},
	
	ready: function(){
		this.element.setStyle('background-image', 'url('+this.imageUrl+')');
		this.imageLoaded = true;
		this.fireEvent('complete');
	},
	
	isLoaded: function(){
		return this.imageLoaded;
	},
	
	show: function(){
		this.fx.start(1);
		this.fireEvent('show');
	},
	
	hide: function(){
		this.fx.start(0);
		this.fireEvent('hide');
	}
	
});

var ColorVariations = {

  init: function(){
    this.container = $('color-variations');
		this.areas = this.container.getElements('area');
		this.swapper = $('product-images');
		this.defaultImageUrl = this.container.get('class');
		this.img = this.container.getElement('img');
		
		// hide focus in IE
		if (this.img && Browser.Engine.trident) this.img.hideFocus = true;
		if (this.img) this.img.show();
	
		this.timer = null;
		
		this.images = [];
		this.bubbles = [];
		
		this.current = 0;
		
		this.count = 0;
		
		// read anchor and show color variation on load
		this.anchor = new URI(document.URL).get('fragment');
		if (this.anchor){
      var index = this.areas.indexOf(this.container.getElement('area[href*='+this.anchor+']'));
			if (index > -1) this.current = index;
		}
	
  	// replace image with div and overlay div with hidden image to prevent bubble problem
		if (this.img){
			this.imgCoords = this.img.getCoordinates(this.container);
			this.clone = new Element('div', {
				'id': 'color-variations-clone',
				'styles': this.imgCoords
			}).inject(this.img, 'before');
			this.clone.setStyles({
				'background-image': 'url('+this.img.get('src')+')',
				'top' : 0
			});
			this.img.setStyles($extend(this.imgCoords, {'position': 'absolute', 'opacity': 0.001}));
		}
		
		// area events
		this.areas.each(function(area, index){
			var url = area.get('href');
			// create product image
			this.images[index] = new ProductImage(url, this.swapper);
			// bubble
			this.bubbles[index] = new Bubble(area);
			area.addEvent('click', function(event){
			  event.stop();
				this.show(index);
			}.bind(this));
			
		}, this);
		
		this.count = (this.areas.length - 1).limit(0, this.areas.length);

    // no variations: load default
		if (this.count == 0){
			this.images[0] = new ProductImage(this.defaultImageUrl+'.jpg', this.swapper);
		}
		
		// prepare arrows for other colors
		if (this.count > 0){
			this.colorArrows = new Element('div', {
			  'id': 'color-arrows'
			}).fade(0);

      this.previousArrow = new Element('span', {
			  'class': 'left',
				'events': {
					'click': function(event){
						event.stop();
						this.show('previous');
					}.bind(this),
					'mouseenter': function(){
						this.previousArrow.addClass('active');
						if (this.current != 0) this.previousArrow.fade(1);
					}.bind(this),
					'mouseleave': function(){
						this.previousArrow.removeClass('active');
						if (this.current != 0) this.previousArrow.fade(0.5);
					}.bind(this)
				}
			}).inject(this.colorArrows).fade(this.current == 0 ? 'hide' : 0.5);
			
			//this.previousArrowFx = new Fx.Tween(this.previousArrow, { property: 'opacity', duration: 300, link: 'cancel' });
			//this.current ? this.previousArrowFx.hide() : this.previousArrowFx.start(0.5);
			
			this.nextArrow = new Element('span', {
			  'class': 'right',
				'events': {
					'click': function(event){
						event.stop();
						this.show('next');
					}.bind(this),
					'mouseenter': function(){ 
					  this.nextArrow.addClass('active');
						if (this.current != this.count) this.nextArrow.fade(1);
					}.bind(this),
					'mouseleave': function(){
						this.nextArrow.removeClass('active');
						if (this.current != this.count) this.nextArrow.fade(0.5);
					}.bind(this)
				}
			}).inject(this.colorArrows).fade(0.5);
			
			this.colorArrows.inject($('main-content')).fade('hide').fade('in');

		}
		
		// show first
		this.show(this.current);
		
	},
	
	show: function(type){
		if (!$defined(type)) direction = 'next';
		
  	var next = this.current;
		
		if ($type(type) == 'string'){
      switch (type){
				case 'previous':
					next -= 1;
				break;
				case 'next':
					next += 1;
				break;
			}
		}
		
		if ($type(type) == 'number') next = type;
		
	  next = next.limit(0, this.count);
		
    if (this.count > 0) this.images[this.current].hide();
		this.images[next].show();
		this.current = next;
    
		if (this.count > 0) {
			// change arrow visibility
			this.current == 0 ? this.previousArrow.fade(0) : this.previousArrow.fade(this.previousArrow.hasClass('active') ? 1 : 0.5);
			this.current == this.count ? this.nextArrow.fade(0) : this.nextArrow.fade(this.nextArrow.hasClass('active') ? 1 : 0.5);
		}
		
	}
	
 };
 
 
var Slideshow = new Class({
	
	Implements: Events,

  options: {
		imagePath: '/img/hp-slideshow-{i}.jpg',
		duration: 10000,
		fxDuration: 500
	},
	
  initialize: function(container){
		this.container = $(container);
		this.range = (this.container.get('class').split(':'))[1].toInt();
		
		this.paths = [];
		for (var i = 1; i < this.range; i++){
			this.paths.push(this.options.imagePath.substitute({i: i}));
		}
		
		this.slides = [];
		this.slides.push(this.container.getElement('.image'));
		this.current = 0;
		this.slideFx = [];
		this.slideFx[0] = new Fx.Tween(this.slides[0], { property: 'opacity', duration: this.options.fxDuration, link: 'cancel' }).set(1);
		this.count = 1;
		this.timer = null;
		
		
		this.images = new Asset.images(this.paths, {
		  onComplete: function(){
				this.fireEvent('build');
			}.bind(this)
		});
		
		// class events
		this.addEvents({
		  'build': function(){ this.createSlides(); },
			'start': function(){ this.start(); }
		});
		
	},
	
	createSlides: function(){
		this.images.each(function(image, index){
			this.slides[index+1] = new Element('div', {
			  'class': 'image',
				'styles': {
					'background-image': 'url('+image.src+')'
				}
			});
			this.slideFx.include(new Fx.Tween(this.slides[index+1], { property: 'opacity', duration: this.options.fxDuration, link: 'cancel' }).set(0));
			this.slides[index+1].inject(this.container);
		}, this);
		
		this.fireEvent('start');
	},
	
	start: function(){
		this.count = this.slides.length;
		this.timer = this.move.periodical(this.options.duration, this);
	},
	
	move: function(){
		this.slideFx[this.current].start(0);
		this.current = ++this.current%this.count;
		this.slideFx[this.current].start(1);
	}
	
});

var Homepage = {
	
	init: function(){
		
		// slider
		this.container = $('slider');
		this.position = $('slider-position');
		this.items = this.container.getElements('.item');
		this.width = {
			window: this.container.getStyle('width').toInt(),
			scroll: 900,
			total: (this.items.length+0.5) * 275
		}
		this.position.setStyle('width', this.width.total);
		this.scrollbar = $('scrollbar');
		this.knob = $('knob');
		
		if (this.width.total > this.width.window) this.createScrollbar();
		
		this.items.each(function(item){
		  var img = item.getElement('img');
			img.addEvent('click', function(event){
			  event.stop();
				window.location = item.getElement('a').get('href');
			});
			img.setStyle('cursor', 'pointer');
		});
		
	},
	
	createScrollbar: function(){
		this.knob.setStyle('width', (this.width.scroll*this.width.scroll/this.width.total).toInt());
		this.scrollbar.setStyle('visibility', 'visible');
		this.slider = new Slider('scrollbar', 'knob', {
		  offset: -3,
			range: [0, this.width.total - this.width.window],
			onChange: function(step){
				this.position.setStyle('left', -step);
			}.bind(this)
		});
		
		this.container.addEvent('mousewheel', function(event){
		  event.stop();
		  var delta = -(event.wheel * 50);
			var left = (-this.position.getStyle('left').toInt() + delta).limit(0, this.width.total - this.width.window);
			this.position.setStyle('left', -left.toInt());
			this.slider.set(left);
		}.bind(this));
	}
	
 };

var InputValidator = new Class({

  Implements: [Options, Events],
	
  options: {
		required: false,
		tests: []
	},
	
  initialize: function(input, options){
		this.setOptions(options);
		this.input = $(input);
		this.tests = new Array(this.options.tests).flatten();
		this.errors = [];
		this.input.addEvent('blur', function(){
		  this.validate();
		}.bind(this));
		
		this.errorMark = null;
		
		// events
		this.addEvent('error', function(event){
		  this.placeErrors();
		});
		this.addEvent('success', function(){
		  this.removeErrors();
		});
		
		return this;
	},
	
	addTest: function(test, message){
		this.tests.include(test, message);
	},
	
	validate: function(){
		this.errors.empty();
		var value = this.input.value.trim();
		if (value == ''){
			if (this.options.required) this.errors.include('Toto pole je povinné.');
		} else {
			this.tests.each(function(test){
				value.test(test.regexp) ? this.errors.erase(test.message) : this.errors.include(test.message);
			}, this);
		}
		this.errors.length ? this.fireEvent('error') : this.fireEvent('success');
	},
	
	getError: function(){
		return this.errors;
	},
	
	placeErrors: function(){
	  var parent = this.input.getParent('p');
		var message = this.errors.join('<br />');
		if (this.errorMark) this.errorMark.destroy();
		this.errorMark = new Element('span',{
		  'class': 'error-mark',
			'text': message
		}).inject(parent);
		parent.addClass('error');
	},
	
	removeErrors: function(){
	  var parent = this.input.getParent('p');
		parent.removeClass('error');
		if (this.errorMark) this.errorMark.destroy();
	}
	
});

var FormOrder = {
	
	init: function(){
		
		this.form = $('form-order');
		
		this.validatedItems = [
  		new InputValidator('form-order-name',    { required: true }),
			new InputValidator('form-order-surname', { required: true }),
			new InputValidator('form-order-email',   { tests: { regexp: /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/, message: 'Zadaná emailová adresa je neplatná.' } }),
			new InputValidator('form-order-phone',   { required: true, tests: { regexp: /^[0-9 ]{9,12}$|^[0-9\+ ]{13,16}$/, message: 'Neplatný formát telefonního čísla.' } })
		];
		
		this.carpets = this.form.getElement('.carpets');
		if (this.carpets){
			this.carpets.set('slide', { duration: 300, link: 'cancel' });
			this.carpets.slide('hide');

      this.radios = this.form.getElements('.type input');
			this.radios.each(function(radio){
  			radio.addEvent('change', function(){
					this.carpets.slide(this.form.getElement('.type input:checked').value == 2 ? 'in' : 'out');
				}.bind(this));
				radio.getParent('label').addEvent('click', function(event){
				  radio.blur();
				});
			}, this);
			
			this.checked = this.form.getElement('.type input:checked');
			if (this.checked) this.carpets.slide(this.checked.value == 2 ? 'in' : 'out');
  	}
		
		
		this.form.addEvent('submit', function(event){
		  event.stop();
		  if (this.isValid()){
				this.form.submit();
			} else {
				alert('Prosím, vyplňte správně všechna požadovaná pole.');
			}
		}.bind(this));
		
		// anti
		this.form.getElement('noscript').destroy();
		new Element('input', {
		  'type': 'hidden',
			'name': 'anti',
			'value': 'kymo'
		}).inject(this.form);

	},
	
	isValid: function(){
		var errors = 0;
		this.validatedItems.each(function(item){
			item.validate();
			errors += item.getError().length;
		});
		return !errors;
	}
	
 };


var Kymo = {
	
	init: function(){
		
		if ($('color-variations')) ColorVariations.init();
		
		// Product categories and product items
	  $$('#product-categories .category, .product-items .item').each(function(item){
			var link = item.getElement('a');
			if (link){
				link.addEvent('click', function(event){
					event.preventDefault();
				});
				item.addEvent('click', function(event){
					event.stop();
					window.location = link.get('href');
				});
				item.setStyle('cursor', 'pointer');
			}
		});
		
		
		// Footer
/*
		if ($('giant')){
			$('giant').getElement('img').set({
			  'styles': {
					'cursor': 'pointer'
				},
				'events': {
					'click': function(){
						window.open(this.getPrevious('a').get('href'));
					}
				}
			});
			$('giant').getElement('a').setStyle('cursor', 'default');
		}
*/
		// Homepage
		if ($('page-homepage')) Homepage.init();
		
		// Stripe table
		$$('table.zebra').each(function(table){
		  table.getElements('tbody tr:nth-child(2n)').addClass('even');
		});
		
		if ($('form-order')) FormOrder.init();
		if ($('slideshow')) new Slideshow('slideshow'); 
	}
	
 };

window.addEvent('domready', function(){
 
 
  Kymo.init();

});
