/*
*	<ul id="navigation">
*		<li id="test_1">test 1<span class="sortable">move</span></li>
*		<li id="test_3">test 2<span class="sortable">move</span></li>
*		<li id="test_4">test 3<span class="sortable">move</span></li>
*		<li id="test_2">test 4<span class="sortable">move</span></li>
*	</ul>
*
*	var sort = new i4_Sort('navigation', 'sort.ajax.php');
*	sort.set_handles('.sortable');
*	sort.run();
*/

i4_Sort = {
	instances: [],
	
	factory: function(id, ajax_file){
		var instance = new i4_Sort_instance(id, ajax_file);
		this.instances.push(instance);
		return instance;
	},
	
	get: function(id) {
		var result = false;
		this.instances.each(function(item){
			if (!result && $(id).up('#'+item.id)) {
				result = item;
			}
		});
		
		return result;
	}
}

var i4_Sort_instance = Class.create({
	id: '', // sortierungs container
	ajax_file: '',
	new_order_id: '', // hidden field id für new_order (send_type post)
	
	current_order: [],
	new_order: [],
	moved_element_id: '', // id of element in database
	moved_item: '', // dom-element
	prev_item: '',
	next_item: '',
	
	handles: 'li', // elemente mit welche man verschieben kann
	tag: 'li', // elemente welche verschoben werden sollen
	only: '', // nur elemente mit einer bestimmten class verschieben
	constraint: 'vertical', // default bewegungseinschraenkung bei Sortable
	column: false, // false => used for navigation
	
	send_type: 'ids', // 'ids' für navigation, 'list' für aggregator, 'post' für form_element_item
	item_selector: '',
	
	/**
	* @param id: id des sortierungs-containers.
	* #param ajax_file: pfad zum ajax php file welches die sortierung uebernimmt.
	*/
	initialize: function(id, ajax_file) {
		this.id = id;
		this.ajax_file = ajax_file;
	},
	
	/**
	* setter
	*/
	set_tag: function (tag) { this.tag = tag; return this; },
	set_only: function (only) { this.only = only; return this; },
	set_handles: function(str){ 
		this.handles = str; 
		
		$$('.'+this.handles).each(function(item){
			item.setStyle({ 'cursor': 'move' });
		});
		
		return this;
	},
	set_constraint: function (constraint) { this.constraint = constraint; return this; },
	set_column: function (column) { this.column = column; return this; },
	set_send_type: function (send_type) { this.send_type = send_type; return this; },
	set_new_order_id: function (new_order_id) { this.new_order_id = new_order_id; return this; },
	
	/**
	* startet sortable.
	*/
	run: function(){
	
		if($(this.id)){
			// log(this.id);
			
			// generate item selector
			this.item_selector = '#'+this.id+' > '+this.tag;
			if (this.only != '') {
				this.item_selector += '.'+this.only;
			}
			// log(this.item_selector);
			// log(this.tag);
			// log(this.only);
			
			// create a temp-hander, where no handler exists
			$$(this.item_selector+' > .temp_handler').each(function(item){ item.remove(); });
			$$(this.item_selector).each((function(item){
			    if (!item.down('.'+this.handles)) {
			    	item.insert(
			    		new Element('span').
			    			addClassName(this.handles).
			    			addClassName('temp_handler').
			    			hide()
			    	);
			    }
			}).bind(this));
			

			var overlap = this.constraint;
			if (overlap == '') {
				overlap = 'horizontal';
			}

			Sortable.create(this.id,{
				
				onUpdate: (function(item){
					this.update_order('new');
					this.save_changes();
					this.renew_class_names();
					
					// wird für ie7 gebraucht
					this.renew_moved_item();

					// sets the z-index from 1000 to auto after dragged. (ie7 doesn't need this)
					if (!Prototype.Browser.IE7 && !Prototype.Browser.IE6) {
						setTimeout((function(){
							this.moved_item.setStyle({ 'zIndex': 'inherit' }); // 'z-index' doesn't work in ie8!
						}).bind(this), 100);
					}
				}).bind(this),
				
				onChange: (function(item){
					var id_array = item.id.split('_');
					this.moved_element_id = id_array[id_array.size()-1];
					this.moved_item = item;
					
					this.renew_class_names();
				}).bind(this),
				
				handles: $$('#'+this.id+' .'+this.handles),
				tag: this.tag,
				only: this.only,
				constraint: this.constraint,
				overlap: overlap
			}); 
			
			this.update_order('current');
			
			// wird für ie7 gebraucht
			this.renew_moved_item();
			
		}
	},
	
	/**
	* zustaendig fuer das updaten der beiden order-arrays. 
	* @param which: welches array soll updated werden. new oder current.
	*/
	update_order: function(which){
		var serialised = '&'+Sortable.serialize(this.id);
		var order = serialised.split('&'+this.id+'[]=');
		if(which == 'current'){ this.current_order = order; }
		if(which == 'new'){ this.new_order = order; }
	},
	
	/**
	* speichert die veraenderung mit ajax
	*/
	save_changes: function(){
		// ermitteln welches das neue uebergeortnete element ist
		this.new_order.each( (function(item, i){
			if(item == this.moved_element_id){
				this.prev_item = this.new_order[i-1];
				this.next_item = this.new_order[i+1];
			}
		}).bind(this));
		
		if (this.prev_item == '') {
			this.prev_item = 0;
		}
		if (this.next_item === undefined) {
			this.next_item = 0;
		}
		
		// für navigation (default)
		if (this.send_type == 'ids') {
			var params = '&call=move&move_id='+this.moved_element_id+'&preceding_id='+this.prev_item+'&following_id='+this.next_item;
		}
		// für aggregator
		if (this.send_type == 'list') {
			var params = '&call=move&new_order='+this.new_order;
		}
		// für form element items
		if (this.send_type == 'post') {
			if (this.new_order_id != '') {
				$(this.new_order_id).value = this.new_order;
			}
		}
		// log(params);
		if (this.send_type != 'post') {
			i4_Message.progress();

			// new Ajax.Updater('footer', this.ajax_file+params,{
			new Ajax.Request(this.ajax_file+params,{ 
				evalScripts: true, 
				asynchronous: true,
				onComplete: function(){	
					i4_Message.show('Änderung gespeichert!');
				}
			});
		}
		
		this.update_order('current');
	},
	
	renew_class_names: function(){
		var elements = $$(this.item_selector);
		var count_elements_in_full_rows = (elements.size() / this.column).floor()*this.column;
		
		$$('#'+this.id+' > '+this.tag+'.aggregator_clear').each(function(item){
			item.remove();
		});
		
		elements.each((function(item, i){
			item.removeClassName('first_column');
			item.removeClassName('last_column');
			item.removeClassName('last_element');
			item.removeClassName('first_element');
			item.removeClassName('last_row');

			if(this.column > 1 && (i+1) % this.column == 1){ 
				item.addClassName('first_column');
			}
			if(this.column > 1 && (i+1) % this.column == 0){ 
				item.addClassName('last_column');
			}
			if((i+1) % this.column == 0){ 
				item.insert({
					after: new Element('div', {'className': 'clear aggregator_clear'})
				});
			}
			if(i == 0){
				item.addClassName('first_element');	
			}

			if((i+1) == elements.size()){
				item.addClassName('last_element');	
				
				if (this.column == 1) {
					item.addClassName('last_row');	
				}
			}

			if(elements.size() % this.column == 0){
				if((count_elements_in_full_rows - (i+1)) < this.column){
					item.addClassName('last_row');	
				}	
			}else{
				if((i+1) > count_elements_in_full_rows){
					item.addClassName('last_row');	
				}	
			}
			
		}).bind(this));
		
	},
	
	renew_moved_item: function(){
		// just in navigation with one .current element
		if ($$('#'+this.id+' .current').size() > 0) {
			$$(this.item_selector).each((function(item){				
				if(this.tag == 'li' && !item.hasClassName('current')){
					item.setStyle({ 'position': 'static' });
				}
			}).bind(this));
		}
	}
	

});
