var HorizontalSortables = new Class({

	options: {
		handles: false,
		onStart: Class.empty,
		onComplete: Class.empty,
		ghost: true,
		snap: 3,
		offset: 0,
		radius: 4,
		ghostOpacity: 0.7,
		dummy: null,
		onDragStart: function(element, ghost){
			var sizes = element.getCoordinates();
			var border = this.options.dummy.getStyle('border-width').toInt() || 0;
			
			if (this.options.ghost) {
				ghost.inject(this.list);
				ghost.setStyles({
					'opacity': this.options.ghostOpacity,
					'width': sizes.width,
					'height': sizes.height
				});
			};
			if (sizes.width == this.list.getSize().size.x) sizes.width = element.getFirst().getSize().size.x;
			if (!sizes.height) sizes.height = element.getFirst().getSize().size.y;
			this.tmp = new Element('div', {
				'class': 'drophere',
				'styles': {
					'margin': element.getStyle('margin'),
					'width': sizes.width - (border * 2),
					'height': sizes.height - (border * 2),
					'-moz-border-radius': this.options.radius + 'px',
					'-webkit-border-radius': this.options.radius + 'px'
				}
			}).inject(element, 'before');
			element.setStyle('display', 'none');
		},
		onDragComplete: function(element, ghost){
			element.setStyles({'display': '', 'opacity': 1});
			if (this.options.ghost) {
				ghost.remove();
				this.trash.remove();
			}
			this.tmp.remove();
		}
	},

	initialize: function(list, options){
		this.setOptions(options);
		this.list = $(list);
		this.elements = this.list.getChildren().filter(function(el) {
			return !el.hasClass('row-mover');
		});
		this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements;
		this.bound = {
			'start': [],
			'moveGhost': this.moveGhost.bindWithEvent(this)
		};
		for (var i = 0, l = this.handles.length; i < l; i++){
			this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
		}
		this.attach();
		if (this.options.initialize) this.options.initialize.call(this);
		this.bound.move = this.move.bindWithEvent(this);
		this.bound.end = this.end.bind(this);
	},

	attach: function(){
		this.handles.each(function(handle, i){
			handle.addEvent('mousedown', this.bound.start[i]);
		}, this);
	},

	detach: function(){
		this.handles.each(function(handle, i){
			handle.removeEvent('mousedown', this.bound.start[i]);
		}, this);
	},
	
	start: function(event, el){
		this.active = el;
		this.coordinates = this.list.getCoordinates();

		if (this.options.ghost){
			var position = el.getPosition();
			var margin = this.options.marginEl.getCoordinates().left || 0;
			this.offset = event.page.x - position.x;
			this.trash = new Element('div').inject(this.list);
			var left = event.page.x - margin - el.getSize().size.x;
			left = left.limit(0, this.coordinates.width - el.offsetWidth);
			this.ghost = el.clone().inject(this.trash).setStyles({
				'position': 'absolute',
				'left': left,
				'top': 0,
				'z-index': 20
			});
			document.addListener('mousemove', this.bound.moveGhost);
		}
		document.addListener('mousemove', this.bound.move);
		document.addListener('mouseup', this.bound.end);
		this.fireEvent('onDragStart', [el, this.ghost]);
		this.fireEvent('onStart', el);
		event.stop();
	},

	moveGhost: function(event){
		var margin = this.options.marginEl.getCoordinates().left || 0;
		var value = event.page.x - margin - this.ghost.getSize().size.x;
		value = value.limit(0, this.coordinates.width - this.ghost.offsetWidth);
		this.ghost.setStyle('left', value);
		event.stop();
	},

	move: function(event){
		var now = event.page.x;
		this.previous = this.previous || now;
		var up = ((this.previous - now) > 0);
		var prev = this.active.getPrevious();
		var next = this.active.getNext();
		if (prev && prev.hasClass('drophere')) prev = prev.getPrevious() || prev;
		if (next && next.hasClass('drophere')) next = next.getNext() || next;
		if (prev && up && now < prev.getCoordinates().right) this.active.injectBefore(prev);
		if (next && !up && now > next.getCoordinates().left) this.active.injectAfter(next);
		this.tmp.injectAfter(this.active);
		this.previous = now;
	},

	serialize: function(converter){
		return this.list.getChildren().map(converter || function(el){
			return this.elements.indexOf(el);
		}, this);
	},

	end: function(){
		this.previous = null;
		document.removeListener('mousemove', this.bound.move);
		document.removeListener('mouseup', this.bound.end);
		if (this.options.ghost){
			document.removeListener('mousemove', this.bound.moveGhost);
		}
		this.fireEvent('onDragComplete', [this.active, this.ghost]);
		this.fireEvent('onComplete', this.active);
	}

});
HorizontalSortables.implement(new Events, new Options);

var VerticalSortables = new Class({

	options: {
		handles: false,
		onStart: Class.empty,
		onComplete: Class.empty,
		ghost: true,
		snap: 3,
		offset: 0,
		radius: 4,
		ghostOpacity: 0.7,
		dummy: null,
		onDragStart: function(element, ghost){
			var sizes = element.getCoordinates();
			var border = this.options.dummy.getStyle('border-width').toInt() || 0;
			
			if (this.options.ghost) {
				ghost.inject(this.list);
				ghost.setStyles({
					'opacity': this.options.ghostOpacity,
					'width': sizes.width,
					'height': sizes.height
				});
			};
			this.tmp = new Element('div', {
				'class': 'drophere',
				'styles': {
					'clear': 'both',
					'margin': element.getStyle('margin'),
					'width': sizes.width - (border * 2),
					'height': sizes.height - (border * 2),
					'-moz-border-radius': this.options.radius + 'px',
					'-webkit-border-radius': this.options.radius + 'px'
				}
			}).inject(element, 'before');
			element.setStyle('display', 'none');
		},
		onDragComplete: function(element, ghost){
			element.setStyles({'display': '', 'opacity': 1});
			if (this.options.ghost) {
				ghost.remove();
				this.trash.remove();
			}
			this.tmp.remove();
		}
	},

	initialize: function(list, options){
		this.setOptions(options);
		this.list = $(list);
		this.elements = this.list.getChildren().filter(function(el) {
			return !el.hasClass('row-handle');
		});
		this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements;
		this.bound = {
			'start': [],
			'moveGhost': this.moveGhost.bindWithEvent(this)
		};
		for (var i = 0, l = this.handles.length; i < l; i++){
			this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
		}
		this.attach();
		if (this.options.initialize) this.options.initialize.call(this);
		this.bound.move = this.move.bindWithEvent(this);
		this.bound.end = this.end.bind(this);
	},

	attach: function(){
		this.handles.each(function(handle, i){
			handle.addEvent('mousedown', this.bound.start[i]);
		}, this);
	},

	detach: function(){
		this.handles.each(function(handle, i){
			handle.removeEvent('mousedown', this.bound.start[i]);
		}, this);
	},
	
	start: function(event, el){
		this.active = el;
		this.coordinates = this.list.getCoordinates();

		if (this.options.ghost){
			var position = el.getPosition();
			var margin = this.options.marginEl.getCoordinates().top || 0;
			var margins = el.getStyle('margin');
			this.offset = event.page.y - position.y;
			this.trash = new Element('div').inject(this.list);
			var top = event.page.y - this.offset - el.getSize().size.y + 35;
			top = Math.abs(top);
			top = top.limit(35, this.coordinates.height - el.offsetHeight + 35);
			this.ghost = el.clone().inject(this.trash).setStyles({
				'margin': margins,
				'position': 'absolute',
				'left': this.list.getStyle('padding-left').toInt(),
				'top': top,
				'z-index': 20
			});
			document.addListener('mousemove', this.bound.moveGhost);
		}
		document.addListener('mousemove', this.bound.move);
		document.addListener('mouseup', this.bound.end);
		this.fireEvent('onDragStart', [el, this.ghost]);
		this.fireEvent('onStart', el);
		event.stop();
	},

	moveGhost: function(event){
		var margin = this.options.marginEl.getCoordinates().top || 0;
		var value = event.page.y - this.offset - this.ghost.getSize().size.y + 35;
		value = value.limit(35, this.coordinates.height - this.ghost.offsetHeight + 35);
		this.ghost.setStyle('top', value);
		event.stop();
	},

	move: function(event){
		var now = event.page.y;
		this.previous = this.previous || now;
		var up = ((this.previous - now) > 0);
		var prev = this.active.getPrevious();
		var next = this.active.getNext();
		if (prev && prev.hasClass('drophere')) prev = prev.getPrevious() || prev;
		if (next && next.hasClass('drophere')) next = next.getNext() || next;
		if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev);
		if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next);
		this.tmp.injectAfter(this.active);
		this.previous = now;
	},

	serialize: function(converter){
		return this.list.getChildren().map(converter || function(el){
			return this.elements.indexOf(el);
		}, this);
	},

	end: function(){
		this.previous = null;
		document.removeListener('mousemove', this.bound.move);
		document.removeListener('mouseup', this.bound.end);
		if (this.options.ghost){
			document.removeListener('mousemove', this.bound.moveGhost);
		}
		this.fireEvent('onDragComplete', [this.active, this.ghost]);
		this.fireEvent('onComplete', this.active);
	}

});
VerticalSortables.implement(new Events, new Options);


window.addEvent('domready', function() {
	var dummy = new Element('div', {'class': 'drophere', 'styles': {'position': 'absolute', 'display': 'none'}}).inject(document.body);
	var dummy2 = new Element('div', {'class': 'drophere', 'styles': {'position': 'absolute', 'display': 'none'}}).inject(document.body);
	var sectionRows = $$('.section-row');
	var rows = sectionRows.getElement('.spacer').filter(function(row) {
		return row != null;
	});
	var rowsHandles = $$(rows).getElements('.move-handle');
	
	rows.each(function(row, i) {
		if (!rowsHandles[i].length) return;
		else if (rowsHandles[i].length == 1) rowsHandles[i].setStyle('display', 'none');
		else {
			new HorizontalSortables(row, $extend({limit: {y: false}, dummy: dummy, handles: rowsHandles[i], marginEl: $$('#page-bg .wrapper')[0]}, AffinitySettings.horizontal));
		}
	});
	
	var rows = $('vertical-sort');
	var rowsMover = $$('.row-handle');
	if (rows.getChildren().length > 1) {
		new VerticalSortables(rows, $extend({handles: rowsMover, limit: {x: false}, dummy: dummy2, marginEl: $$('#page-bg .wrapper')[0]}, AffinitySettings.vertical));
	} else {
		rowsMover.setStyle('display', 'none');
	}

	/*var rows = $('sections');
	var rowsMover = $$('.row-mover');
	
	var blocks = $$('.section-row');
//	var blocksMover = $$('.mover-handle');

	blocks.each(function(block) {
		var tmp = block.getElements('.mover-handle');
		new HorizontalSortables(block, {offset: 28, limit: {y: false}});
	});
	new Sortables(rows, {handles: rowsMover, limit: {x: false}});*/
});