
Ext.ns('LSI.Widgets');

LSI.Widgets.AjaxSearchGrid = Ext.extend(Object, {

		localisationFieldQueryUrl : '/lsi-ajax/localisationSearch.php',

		localisationFieldTpl : '<div class="item"><div class="matched">{matched}</div> <div class="postalcode">{postalcode}</div></div>',

		localisationFieldNumResults : 15,

		localisationFieldDatas : null,

		localisationListBoxVisible : false,

		autoFocus : false,

		typingAheadDelay : 50,

		anims : {
			listBox : { duration: 0.2 }
		},

		constructor : function(config) {

			Ext.apply(this, config);

			this.el = Ext.get(this.el);

			if (!this.el) throw 'El not found';

			Ext.Ajax.disableCaching = false;

		},

		init : function() {

			this.initFocus();
			this.initLocalisationField();
			this.initExtendsField();
			this.initTypeField();
			this.initRoomsField();

			this.initMoreCriteriasBox();

			this.el.child('form').on('submit', function() {
					this.el.select('button').set({disabled:true});
					this.el.mask("Recherche en cours");
				}, this);

		},

		// Try to focus a field with class "firstFocus"
		initFocus : function() {

			if (!this.autoFocus)
				return;

			this.el.select('.firstFocus').each(function(el) {
					try {

						// are we in a tab panel ?
						if (el.up('.tabContent')) {
							// if yes, is it active ?
							if (el.up('.tabContent-active')) {
								// ok, focus !
								el.focus();
							}
						} else {
							el.focus();
						}

					} catch (e) {}
				});

		},

		// Localisation Field

		initLocalisationField : function() {

			var field, localisationCache;

			localisationCache = {};

			field = this.el.child('input.localisation');
			if (!field) return;

      field.dom.setAttribute("autocomplete","off");

			this.localisationFieldEl = field;

			field.on('keypress', function(e) {
					if (e.getKey() == 13) e.stopEvent();
				});

			field.on('keyup', function(e) {

					var uri, query;

					// key navigation
					switch (e.getKey()) {
					case 38: // UP
						this.localisationFieldNavigate(-1);
						return;
					case 40: // DOWN
						this.localisationFieldNavigate(1);
						return;
					case 13: // ENTER
						if (!this.localisationFieldSelect(null)) {
							this.el.child('form').dom.submit();
						}
						return;
					case 9:  // TAB
						return;
					case 27: // ESCAPE
						this.hideLocalisationListBox();
						return;
					default: break;
					}

					// get last token, and trim
					query = field.getValue().split(',');
					query = query[query.length-1].replace(/^ +| +$/g, '');

					// validate
					if (query.length < 2 || query.match(/[()]/)) {
						this.hideLocalisationListBox();
						return;
					}

					if (localisationCache[query]) {

						this.showLocalisationListBox(localisationCache[query]);

					} else {

						Ext.Ajax.request({
								url            : this.localisationFieldQueryUrl,
								method         : 'GET',
								params         : { loc:query, num:this.localisationFieldNumResults},
								scope          : this,
								disableCaching : false,
								success        : function(response, options) {

									var list = [], tokens, subTokens, i;

									tokens = response.responseText.split('\r');
									for (i = 0; i < tokens.length; i++) {
										subTokens = tokens[i].split('\n');
										if (subTokens.length == 5)
											list.push({
													name       : subTokens[0],
													nicename   : subTokens[1],
													postalcode : subTokens[2],
													matched    : subTokens[3],
													type       : subTokens[4]
												});
									}

									if (list.length === 0) list = false;

									localisationCache[query] = list;

									this.showLocalisationListBox(list);

								}
							});

					}

				}, this, { buffer : this.typingAheadDelay });

			// listen to 'unfocus'
			field.on('blur', this.hideLocalisationListBox, this, {delay:200});

		}, 

		showLocalisationListBox : function(data) {

			var listBox, tpl, ul, index = 0;

			this.hideAllListsBox();

			if (!data) data = this.localisationFieldDatas;
			if (!data) {
				this.hideLocalisationListBox();
				return;
			}

			tpl = new Ext.Template(this.localisationFieldTpl);

			listBox = this.getLocalisationListBox();
			listBox.update('');

			ul = listBox.createChild({tag:'ul'});

			Ext.each(data, function(city) {
					tpl.append(ul, city).viewIndex = index;
					index++;
				});

			ul.child('.item').addClass('over');

			this.localisationFieldDatas = data;
			this.localisationListBoxVisible = true;
			listBox.show();

		},

		hideLocalisationListBox : function() {

			if (!this.localisationListBoxVisible) return;

			this.localisationListBoxVisible = false;
			this.getLocalisationListBox().hide();

		},

		getLocalisationListBox : function() {

			var listBox, xy;

			listBox = this.el.createChild({cls : 'listBox localisationListBox'});
			listBox.hide();

			xy = this.localisationFieldEl.getXY();
			xy[1] += this.localisationFieldEl.getHeight() + 2;
			listBox.setXY(xy);

			// listen to 'overing' on item elements
			listBox.on('mouseover', function(e, node) {

					Ext.get(node).radioClass('over');

				}, this, {delegate : '.item'});

			// listen to 'click' on item elements
			listBox.on('click', function(e, node) {

					this.localisationFieldSelect(node.viewIndex);
					 
				}, this, {delegate : '.item'});

			// memoize
			return (this.getLocalisationListBox = function() {

					return listBox;

				})();

		},

		localisationFieldNavigate : function(direction) {

			var listBox, el, newEl;

			listBox = this.getLocalisationListBox();

			try {

				// look for current 'over'
				el = listBox.child('.item.over');

				if (el) {

					// select next (or previous)
					if (direction == 1)
						newEl = el.next();
					else
						newEl = el.prev();

				}

				if (!newEl) {

					el = listBox.child('.item');
					
					if (direction == 1)
						newEl = el.parent().first();
					else
						newEl = el.parent().last();

				}

				if (!newEl) return;

				if (!this.localisationListBoxVisible)
					this.showLocalisationListBox();
				newEl.radioClass('over');


			} catch (e) {

			}

		},

		localisationFieldSelect : function(index) {

			var listBox, el, selected, value;

			listBox = this.getLocalisationListBox();

			if (Ext.isEmpty(index)) {
				if (!this.localisationListBoxVisible) return false;
				el = listBox.child('.item.over');
				if (!el || Ext.isEmpty(el.dom.viewIndex)) return false;
				index = el.dom.viewIndex;
			}

			try {
				selected = this.localisationFieldDatas[index];

				if (!selected) return false;

				this.hideLocalisationListBox();
				this.localisationFieldDatas = null;
				this.localisationFieldEl.focus();

				value = this.localisationFieldEl.getValue().split(',');
				value.length--;
				value.push(selected.nicename + ' (' + selected.postalcode + ')', "");
				this.localisationFieldEl.dom.value = value.join(', ');

			} catch (e) {
				return false;
			}

			return true;

		},

		// Extends Field

		initExtendsField : function() {

			var inputs = this.el.select("input.extends");

			inputs.each(function(input) {
					input.on("click", function(e, input) {
							// play as a radio box
							if (input.checked) {
								inputs.each(function(i) {
										if (i.dom !== input && i.dom.checked)
											i.dom.checked = false;
									});
							}
						});
				});

		},

		// Type Field

		initTypeField : function() {

			var field, typeBox;

			field = this.el.child('input.type');
			if (!field) return;

      field.dom.setAttribute("autocomplete","off");

			this.typeFieldEl = field;

			// create an hidden field, containings real values
			this.typeFieldHiddenEl = field.parent().createChild({
					tag : 'input',
					type: 'hidden',
					name: field.dom.name
				});
			field.dom.name = "";

			this.typeBoxUpdate();
			typeBox = this.getTypeListBox();

			// auto show type box list
			field.hover(this.showTypeListBox, function() {}, this);
			typeBox.hover(function() {}, this.hideTypeListBox, this);

		},

		getTypeListBox : function() {

			var typeBox, field, fieldValue, xy, id, cb;

			if (!this.typeFieldEl) return null;

			field = this.typeFieldEl;
			fieldValue = field.dom.value;
			field.dom.value = "";

			typeBox = this.el.createChild({cls : 'listBox typeListBox'});
			typeBox.hide();

			for (key in this.types) {
				id = Ext.id();
				cb = {
					tag   : 'input',
					type  : 'checkbox',
					id    : id,
					name  : this.types[key],
					value : key
				};
				if (fieldValue.indexOf(key) !== -1) cb.checked = "checked";
				typeBox.createChild({
						cls : 'item',
						cn  : [cb,{
							tag     : 'label',
							cls     : 'boxLabel',
							html    : this.types[key],
							htmlFor : id
						}]
					});
			}

			// change class on 'overing' on item elements
      typeBox.select('.item').addClassOnOver('over');

			// listen to 'click' events on items
			typeBox.on('click', this.typeBoxUpdate, this, {delegate : 'input'});

			// memoize
			return (this.getTypeListBox = function() {

					xy = field.getXY();
					xy[1] += field.getHeight() + 2;
					typeBox.setXY(xy);
					return typeBox;

				})();

		},

		typeBoxUpdate : function() {

			var displayVals = [], internalVals = [];

			this.getTypeListBox().select('input').each(function(i) {
					if (i.dom.checked) {
						displayVals.push(i.dom.name);
						internalVals.push(i.dom.value);
					}
				});

			this.typeFieldEl.dom.value = displayVals.join(', ');
			this.typeFieldHiddenEl.dom.value = internalVals.join(', ');

		},

		showTypeListBox : function() {

			var el, h;

			try {
				this.hideAllListsBox();
				this.autoHideAllListsBox();
				this.stopAnims();

				el = this.getTypeListBox();
				h = el.hide().setHeight().getHeight();
				el.setHeight(0).show().setHeight(h, this.anims.listBox);

			} catch (e) {}
		},

		hideTypeListBox : function() {
			try {
				this.getTypeListBox().hide();
			} catch (e) {}
		},

		// Rooms Field

		initRoomsField : function() {

			var field, roomsBox;

			field = this.el.child('input.rooms');
			if (!field) return;

      field.dom.setAttribute("autocomplete","off");

			this.roomsFieldEl = field;

			roomsBox = this.getRoomsListBox();

			// auto show rooms box list
			field.hover(this.showRoomsListBox, function() {}, this);
			roomsBox.hover(function() {}, this.hideRoomsListBox, this);

			this.roomsBoxUpdate();

		},

		getRoomsListBox : function() {

			var roomsBox, xy, id, rooms, field, fieldValue;

			rooms = {
				"1" : "1 pièce",
				"2" : "2 pièces",
				"3" : "3 pièces",
				"4" : "4 pièces",
				"5 et +" : "5 pièces et plus"
			};

			if (!this.roomsFieldEl) return null;

			field = this.roomsFieldEl;
			fieldValue = field.dom.value;

			roomsBox = this.el.createChild({cls : 'listBox roomsListBox'});
			roomsBox.hide();

			for (key in rooms) {
				id = Ext.id();
				cb = {
					tag   : 'input',
					type  : 'checkbox',
					id    : id,
					name  : rooms[key],
					value : key
				};

				if (fieldValue.indexOf(key) !== -1) cb.checked = "checked";

				roomsBox.createChild({
						cls : 'item',
						cn  : [cb,{
							tag     : 'label',
							cls     : 'boxLabel',
							html    : rooms[key],
							htmlFor : id
						}]
					});
			}

			// change class on 'overing' on item elements
      roomsBox.select('.item').addClassOnOver('over');

			// listen to 'click' events on items
			roomsBox.on('click', this.roomsBoxUpdate, this, {delegate : 'input'});

			// memoize
			return (this.getRoomsListBox = function() {

					xy = field.getXY();
					xy[1] += field.getHeight() + 2;
					roomsBox.setXY(xy);

					return roomsBox;

				})();

		},

		roomsBoxUpdate : function() {

			var values = [];

			this.getRoomsListBox().select('input').each(function(i) {
					if (i.dom.checked) {
						values.push(i.dom.value);
					}
				});

			if (values.length === 0) {
				this.roomsFieldEl.dom.value = "indifférent";
				this.roomsFieldEl.addClass('empty');
			} else {
				this.roomsFieldEl.dom.value = values.join(', ');
				this.roomsFieldEl.removeClass('empty');
			}

		},

		showRoomsListBox : function() {

			var el, h;

			try {
				this.hideAllListsBox();
				this.autoHideAllListsBox();
				this.stopAnims();
				el = this.getRoomsListBox();
				h = el.hide().setHeight().getHeight();
				el.setHeight(0).show().setHeight(h, this.anims.listBox);

			} catch (e) {}
		},

		hideRoomsListBox : function() {
			try {
				this.getRoomsListBox().hide();
			} catch (e) {}
		},

		// More Criterias...
		initMoreCriteriasBox : function() {

			var boxEl, linkEl;

			boxEl = this.el.child('.moreCriterias');
			if (!boxEl) return;

			boxEl.setHeight(0).hide();

			linkEl = this.el.child('.moreCriteriasButton');
			if (!linkEl) return;

			linkEl.show();

			linkEl.on('click', function(e) {

					e.preventDefault();

					var height;

					if (boxEl.hasClass("active")) {

						boxEl.removeClass("active");
						linkEl.removeClass("active");
						boxEl.setHeight(0, true).hide();

					} else {

						height = boxEl.hide().setHeight().getHeight();
						boxEl.addClass("active");
						boxEl.setHeight(0).show().setHeight(height, {
								duration: 0.2,
								callback : function() {linkEl.addClass("active");}
							});

					}

				});


		},

		// Global for lists boxes

		hideAllListsBox : function(e) {
			if (e && e.getTarget('.listBox')) {
				return;
			}
			this.hideRoomsListBox();
			this.hideTypeListBox();
			this.hideLocalisationListBox();
			if (e)
				Ext.get(document).un('click', this.hideAllListsBox, this);
		},

		autoHideAllListsBox : function() {
			Ext.get(document).un('click', this.hideAllListsBox, this);
			Ext.get(document).on('click', this.hideAllListsBox, this);
		},

		// Anims

		stopAnims : function() {
			try{
				this.anims.listBox.anim.stop();
			} catch (e) { }
		}


	});

