/**
 * Autocompleter.Request
 *
 * http://digitarald.de/project/autocompleter/
 *
 * @version		1.1.2
 *
 * @license		MIT-style license
 * @author		Harald Kirschner <mail [at] digitarald.de>
 * @copyright	Author
 */

Autocompleter.Request = new Class({

	Extends: Autocompleter,

	options: {/*
		indicator: null,
		indicatorClass: null,
		onRequest: $empty,
		onComplete: $empty,*/
		postData: {},
		ajaxOptions: {},
		postVar: 'value'

	},

	query: function(){
		var data = Object.clone(this.options.postData) || {};
		data[this.options.postVar] = this.queryValue;
		var indicator = $(this.options.indicator);
		if (indicator) indicator.setStyle('display', '');
		var cls = this.options.indicatorClass;
		if (cls) this.element.addClass(cls);
		this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
		this.request.send({'data': data});
	},

	/**
	 * queryResponse - abstract
	 *
	 * Inherated classes have to extend this function and use this.parent()
	 */
	queryResponse: function() {
		var indicator = $(this.options.indicator);
		if (indicator) indicator.setStyle('display', 'none');
		var cls = this.options.indicatorClass;
		if (cls) this.element.removeClass(cls);
		return this.fireEvent('onComplete', [this.element, this.request]);
	},
	
	update:function(tokens) {
		this.choices.empty();
		this.cached = tokens;
		var type = tokens && typeOf(tokens);
		if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
			(this.options.emptyChoices || this.hideChoices).call(this);
		} else {
			
			
			if (tokens.categories.length > 0) {
				
				/*
				var catHeader = new Element('div',{
						'html' : 'Categories',
						'class': 'completeHeader'
				});
				
				this.addChoiceEvents(catHeader).inject(this.choices);
				console.log(this.options.injectChoice);
				*/
				
				var catI = 0;
				tokens.categories.each(this.options.injectChoice || function(category) {
					
					var catClass = (catI % 2 !=0 ) ? 'even' : '';
					var choice = new Element('li', {
							id : category.cat_id,
							'class' : 'cat ' //+ catClass
					});
					var catName = 'Category: ';
					catName += (category.parent_name != null) ? category.parent_name + " > " : '';
					catName += category.cat_name;
					choice.set('html',catName);
					choice.inputValue = catName;
					this.addChoiceEvents(choice).inject(this.choices);
					catI++;
				}, this);
				
			}
			
			
			
			if (tokens.products.length > 0) {
			
				var prodI = 0;
				/*
				var prodHeader = new Element('div',{
					'html' : 'Products',
					'class': 'completeHeader'
				});
				
				prodHeader.inject(this.choices);
				*/
		
			
				if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
					tokens.products	.each(this.options.injectChoice || function(token){
					
					var prodClass = (prodI % 2 ==0) ? 'even' : '';
					var choice = new Element('li', {
						id: token.products_id,
						'class' : 'prod ' + prodClass
					});
					
					var html = (token.image != '' || token.image != false) ? token.image : '';
					html +=  " " + this.markQueryValue(token.name);
					choice.set('html',html);
					//var choice = new Element('li', {'html': this.markQueryValue(token)});
					choice.inputValue = token.name;
					this.addChoiceEvents(choice).inject(this.choices);
					prodI++;
				}, this);
					
			}
			
			if (tokens.totalRows.length > 0) {
			
				var html  =  tokens.products.length + ' of '+ tokens.totalRows + " product";
				html += (tokens.totalRows > 1) ? "s" : ''+ ".";
				
				var totals = new Element('li',{
					'html': html,
					'class' : 'totals'
				});
				
				totals.inject(this.choices);
			}
			
			this.showChoices();
			
			
		}		
	},
	
	choiceSelect: function(choice) {
		if (typeOf(choice) == 'element') {
			choice = choice;
		} else if (typeOf(choice) == 'array') {
			choice = choice[0];
		}
		
		var type;
		var itemId;
	
		
		if (choice.hasClass('cat')) {
			type = 'cat';
		} else if (choice.hasClass('prod')) {
			type = 'prod';
		}
		itemId = choice.get('id');
		
		$('item_id').value = itemId;
		$('item_type').value = type;
		
		
		
		if (choice) this.choiceOver(choice);
		this.setSelection(true);
		this.queryValue = false;
		this.hideChoices();
	},
	
	choiceOver: function(choice, selection) {
		
		
		if (typeOf(choice) == 'element') {
			choice = choice;
		} else if (typeOf(choice) == 'array') {
			choice = choice[0];
		}
		
		var type;
		var itemId;
	
		
		if (choice.hasClass('cat')) {
			type = 'cat';
		} else if (choice.hasClass('prod')) {
			type = 'prod';
		}
		itemId = choice.get('id');
		
		$('item_id').value = itemId;
		$('item_type').value = type;		
		
		if (!choice || choice == this.selected || choice == null) return;
		if (this.selected) this.selected.removeClass('autocompleter-selected');
		if (typeOf(choice) == 'element') {
			this.selected = choice.addClass('autocompleter-selected');
		} else if (typeOf(choice) == 'array') {
			this.selected = choice[0].addClass('autocompleter-selected');
		}

		
		this.fireEvent('onSelect', [this.element, this.selected, selection]);
		if (!this.selectMode) this.opted = this.element.value;
		if (!selection) return;
		this.selectedValue = this.selected.inputValue;
		if (this.overflown) {
			var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
				top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
			if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
			else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
		}
		if (this.selectMode) this.setSelection();
	}	
});

Autocompleter.Request.JSON = new Class({

	Extends: Autocompleter.Request,

	initialize: function(el, url, options) {
		this.parent(el, options);
		this.request = new Request.JSON(Object.merge({
			'url': url,
			'link': 'cancel'
		}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
	},

	queryResponse: function(response) {
		this.parent();
		this.update(response);
	}

});

Autocompleter.Request.HTML = new Class({

	Extends: Autocompleter.Request,

	initialize: function(el, url, options) {
		this.parent(el, options);
		this.request = new Request.HTML(Object.merge({
			'url': url,
			'link': 'cancel',
			'update': this.choices
		}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
	},

	queryResponse: function(tree, elements) {
		this.parent();
		if (!elements || !elements.length) {
			this.hideChoices();
		} else {
			this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function(choice) {
				var value = choice.innerHTML;
				choice.inputValue = value;
				this.addChoiceEvents(choice.set('html', this.markQueryValue(value)));
			}, this);
			this.showChoices();
		}

	}

});

/* compatibility */

Autocompleter.Ajax = {
	Base: Autocompleter.Request,
	Json: Autocompleter.Request.JSON,
	Xhtml: Autocompleter.Request.HTML
};

