/**
 * @class SearchLocationPanel
 * @extends Ext.form.FormPanel
 *
 * The SearchLocationPanel is located in the left bar of the page, allowing to search cities/streets on the map
 *
 * @author ssmeman
 * @version 1.0
 */

/**
 * @constructor
 * @param {Object} config Configuration options
 */
var maxTokens = 1000;

Roo.gui.SearchLocationPanel = Ext.extend(Ext.form.FormPanel, {
	// configurables
	// anything what is here can be configured from outside
	titleText: messages.searchLocationPanel.title()
	,provincie_emptyText: messages.searchLocationPanel.provincie.emptyText()
	,woonplaats_emptyText: messages.searchLocationPanel.woonplaats.emptyText()
	,straat_emptyText: messages.searchLocationPanel.straat.emptyText()
	,huisnummer_emptyText: messages.searchLocationPanel.huisnummer.emptyText()
	,postcode_emptyText: messages.searchLocationPanel.postcode.emptyText()
	,postcode_regexText: messages.searchLocationPanel.postcode.regexText()
	,buttonSearch: messages.button.showText()
	,buttonErase: messages.button.eraseText()

	,id: 'searchLocationPanel'

	,initComponent:function() {
		// register events this component fires
		this.addEvents(
			'searchedLocation'
			,'foundLocation'
		);

		this.adresStore = new Ext.data.Store({
			proxy: new Ext.ux.data.DwrProxy({
				api: {read: SearchService.findStraatByPostcode }
				,listeners: {
					'beforeload': function(dataProxy, params) {
						params[dataProxy.loadArgsKey] = params.query;
					}
				}
				,scope:this
			})
			,reader: new Ext.data.JsonReader({}, Ext.data.Record.create([
				{name: 'geoid', mapping:'geographicidentifier'}
				,{name: 'boundingBox', mapping:'boundingBox' }
				,{name: 'straatnaam', mapping:'straatnaam' }
				,{name: 'huisnummer', mapping:'huisnummer'}
				,{name: 'woonplaats', mapping:'woonplaats'}
			]))

			,setApi: function(config) {
				this.proxy.setApi(config);
			}
		});

		var provincieStore = new Ext.data.Store({
			proxy: new Ext.ux.data.DwrProxy({
				api: {read: SearchService.listProvincies }
				,listeners: {
					'beforeload': function(dataProxy, params) {
						params[dataProxy.loadArgsKey] = [];
					}
				}
			})
			,reader: new Ext.data.JsonReader({}, Ext.data.Record.create([
				{name: 'geoid', mapping:'geographicidentifier' }
				,{name: 'name', mapping:'naam' }
			]))
		});
		this.gemeenteStore = new Ext.ux.data.CachingStore({
			proxy: new Ext.ux.data.DwrProxy({
				api: {read: SearchService.listWoonplaatsenByToken }
				,listeners: {
					'beforeload': function(dataProxy, params){
						var token = params.query.toUpperCase();

						if(params.byName == true) {
							dataProxy.setApi({read: SearchService.findWoonplaatsByName });
							params[dataProxy.loadArgsKey] = [token];
						}
						else {
							var provCombo = Ext.getCmp('searchLocationPanel_provincie');
							var record;
							if(provCombo.getValue() != '') {
								record = provincieStore.query(provCombo.valueField, provCombo.getValue()).itemAt(0);
							}

							if( record ) {
								dataProxy.setApi({read: SearchService.findWoonplaatsenByToken});
								params[dataProxy.loadArgsKey] = [record.json, token ];
							}
							else {
								dataProxy.setApi({read: SearchService.listWoonplaatsenByToken});
								params[dataProxy.loadArgsKey] = [token];
							}
						}
					}
				}
				,scope:this
			})
			,reader: new Ext.data.JsonReader({}, Ext.data.Record.create([
				{name: 'id', mapping:'geographicidentifier' }
				,{name: 'name', mapping:'naam' }
			]))
		});
		this.straatStore = new Ext.ux.data.CachingStore({
			proxy: new Ext.ux.data.DwrProxy({
				api: {read: SearchService.findStratenByToken}
				,listeners: {
					'beforeload': function(dataProxy, params) {
						var record;
						var plaatsCombo = Ext.getCmp('searchLocationPanel_woonplaats');

						if(plaatsCombo.getValue() != '') {
							record = plaatsCombo.store.query(plaatsCombo.valueField, plaatsCombo.getValue()).itemAt(0);
						}

						if( record ) {
							var token = params.query.substring(0,1).toUpperCase() + params.query.substring(1,maxTokens-1).toLowerCase();
							params[dataProxy.loadArgsKey] = [record.json, token];
						}
						else {
							Ext.Msg.alert(messages.msg.titleWarning(), messages.searchLocationPanel.woonplaats.notSelected());
							return false;
						}
					}
				}
			})
			,reader: new Ext.data.JsonReader({}, Ext.data.Record.create([
				{name: 'id', mapping:'geographicidentifier' }
				,{name: 'name', mapping:'straatnaam' }
			]))
		});

		var config = {
			title: this.titleText
			,autoHeight: true

			,defaults: {
				allowBlank: true
				,hideLabel: true
				,width: 170
				,listWidth: 185
				,loadingText: messages.combo.loadingText()
			},

			items:[{
				xtype: 'label'
				,text: 'Toon locatie/gebied in kaart'
			},{
				xtype: 'combo'
				,id: 'searchLocationPanel_provincie'
				,displayField: 'name'
				,emptyText: this.provincie_emptyText
				,editable: false
				,store: provincieStore
				,triggerAction: 'all'
				,valueField: 'geoid'
			},{
				xtype: 'combo'
				,width: 187
				,id: 'searchLocationPanel_woonplaats'
				,displayField: 'name'
				,emptyText: this.woonplaats_emptyText
				,regex: /^(\S+\s?)*$/
				,validationDelay: 100
				,queryDelay: 250
				,hideTrigger: true
				,minChars: 1
				,forceSelection: false
				,store: this.gemeenteStore
				,valueField: 'id'
			},{
				xtype: 'fieldset'
				,checkboxToggle: false
				,autoHeight: true
				,animCollapse: false
				,hideBorders: true
				,border: false
				,collapsed: false
				,hideLabel: true
				,style: 'padding:0; margin:0 0 -2px 0'
				,layout: 'column'
				,width: 187
				,items:	[{
					columnWidth: .8
					,items: [{
						xtype: 'combo'
						,id: 'searchLocationPanel_straat'
						,displayField: 'name'
						,emptyText: this.straat_emptyText
						,hideTrigger: true
						,forceSelection: false
						,regex: /^(\S+\s?)*$/
						,validationDelay: 100
						,queryDelay: 250
						,minChars: 1
						,store: this.straatStore
						,valueField: 'id'
						,listWidth: 140
						,width: 144
					}]
				},{
					columnWidth: .2
					,items: [{
						xtype: 'textfield'
						,id: 'searchLocationPanel_huisnummer'
						,emptyText: this.huisnummer_emptyText
						,width: 37
					}]
				}]
			},{
				id: 'searchLocationPanel_postcode'
				,xtype: 'textfield'
				,emptyText: this.postcode_emptyText
				,regex: /^[0-9]{4}( ?)[a-zA-Z]{2}$/
				,regexText: this.postcode_regexText
				,width: 80
			}]

			,buttons: [{
				text: this.buttonSearch
				,handler: this.onSearch
			},{
				text: this.buttonErase
				,handler: function(t,e) {
					t.findParentByType('searchLocationPanel').getForm().reset();
				}
			}]
			,keys: {
				key: Ext.EventObject.ENTER
				,scope: this
				,handler: function() {
					this.onSearch(this.buttons[0],null);
				}
			}
		};

		Ext.apply(this, config);
		Ext.apply(this.initialConfig, config);

		// call parent initComponent
		Roo.gui.SearchLocationPanel.superclass.initComponent.apply(this, arguments);

		this.provincieCombo = Ext.getCmp('searchLocationPanel_provincie');
		this.woonplaatsCombo = Ext.getCmp('searchLocationPanel_woonplaats');
		this.straatCombo = Ext.getCmp('searchLocationPanel_straat');
		this.huisnummerCombo = Ext.getCmp('searchLocationPanel_huisnummer');
		this.postcodeCombo = Ext.getCmp('searchLocationPanel_postcode');

		this.provincieCombo.on({
			scope: this
			,select: function(combo, record, index) {
				this.gemeenteStore.reset();
				this.straatStore.reset();

				if(this.woonplaatsCombo.isDirty()) {
					this.woonplaatsCombo.lastQuery = '';
					this.woonplaatsCombo.clearValue();
					this.woonplaatsCombo.reset();
				}

				if(this.straatCombo.isDirty()) {
					this.straatCombo.lastQuery = '';
					this.straatCombo.clearValue();
					this.straatCombo.reset();
				}

				if(this.huisnummerCombo.isDirty()) {
					this.huisnummerCombo.reset();
				}
				if(this.postcodeCombo.isDirty()) {
					this.postcodeCombo.reset();
				}
			}
		});
		this.woonplaatsCombo.on({
			scope: this
			,select: function(combo, record, index) {
				this.straatStore.reset();
				if(this.straatCombo.isDirty()) {
					this.straatCombo.lastQuery = '';
					this.straatCombo.reset();
				}

				if(this.huisnummerCombo.isDirty()) {
					this.huisnummerCombo.reset();
				}
				if(this.postcodeCombo.isDirty()) {
					this.postcodeCombo.reset();
				}
			}
			,beforequery : function(event) {
				if(!event.combo.validate()) {
					event.cancel = true;
				}
			}
		});
		this.straatCombo.on({
			scope: this
			,select: function(combo, record, index) {
				if(this.huisnummerCombo.isDirty()) {
					this.huisnummerCombo.reset();
				}
				if(this.postcodeCombo.isDirty()) {
					this.postcodeCombo.reset();
				}
			}
			,beforequery : function(event) {
				if(!event.combo.validate()) {
					event.cancel = true;
				}
			}
		});
		this.postcodeCombo.on({
			scope: this
			,change: function(combo) {
				this.provincieCombo.clearValue();
				this.provincieCombo.reset();
				this.gemeenteStore.reset();
				this.straatStore.reset();

				if(this.woonplaatsCombo.isDirty()) {
					this.woonplaatsCombo.lastQuery = '';
					this.woonplaatsCombo.reset();
				}

				if(this.straatCombo.isDirty()) {
					this.straatCombo.lastQuery = '';
					this.straatCombo.reset();
				}
			}
		});


		eventHub.on({
			scope: this
			,'receivedUrlParameters': function(parameters) {
				if (parameters.woonplaats) {
					this.expand();

					this.woonplaatsCombo.store.load({
						params: {
							query:parameters.woonplaats
							,byName: true
						}
						,'callback': function(record, options, success) {
							if (success && record.length==1) {
								var loc = {
									boundingBox: record[0].json.boundingBox,
									name: record[0].json.naam,
									parent: record[0].json.provincie,
									type: 'Woonplaats'
								};

								var panel = Ext.getCmp('searchLocationPanel');
								panel.woonplaatsCombo.setValue(loc.name);
								panel.fireEvent('foundLocation', loc);
							} else {
								Ext.Msg.alert(messages.msg.titleError(), messages.searchLocationPanel.woonplaats.notFound(options.params.query));
							}
						}
					});

				}
			}
			,'searchedPlanCriteria': this.onClear
			,'searchedPlanName': this.onClear
			,'searchedPlanId': this.onClear
			,'changedFilter': function(parameters) {
				if(parameters.filter != "NONE") {
					this.getForm().reset();
				}
			}
		});

	} // e/o function initComponent

	,onSearch: function(t,e) {
		var parent = t.findParentByType('searchLocationPanel');
		var values = {};
		var location = {};
		var params = [];

		for(p in parent.getForm().getValues()) {
			var field = parent.getForm().findField(p);

			if (field.getValue().length > 0 ) {
				var f = p.substring(p.lastIndexOf('_')+1);
				values[f] = field.getValue();
				if (parent[f+'Combo'].store) {
					var col = parent[f+'Combo'].store.query(Ext.getCmp(p).valueField, values[f]);
					if(col) {
						location[f] = col.itemAt(0).json;
					}
				}
			}
		}

		Ext.getCmp('searchLocationPanel').fireEvent('searchedLocation');

		if(values.postcode) {
			// strip spaces and optional space between the digits and letters
			values.postcode = values.postcode.replace(' ', '');
			if (!Ext.getCmp('searchLocationPanel_postcode').isValid()) {
				Ext.Msg.alert(messages.msg.titleError(), messages.searchLocationPanel.inValidPostcode());
				return;
			}
			if(values.huisnummer) {
				parent.adresStore.setApi({read:SearchService.findStraatByPostcodeHuisnummer});
				params = [{postcode:values.postcode}, values.huisnummer];
			}
			else {
				parent.adresStore.setApi({read:SearchService.findStraatByPostcode});
				params = [{postcode:values.postcode}];
			}
		}
		else {
			if(values.straat) {
				if (values.huisnummer) {
					parent.adresStore.setApi({read:SearchService.findAdresByStraatHuisnummer});
					params = [location.straat, values.huisnummer];
				}
				else {
					var loc = {
						boundingBox: location.straat.boundingBox,
						type: 'Straat',
						name: location.straat.straatnaam + ', ' + location.straat.parent
					};
					parent.fireEvent('foundLocation', loc);
					return;
				}
			}
			else if(values.woonplaats) {
				var loc = {
					boundingBox: location.woonplaats.boundingBox,
					type: 'Woonplaats',
					name: location.woonplaats.naam + ', ' + location.woonplaats.parent
				};
				parent.fireEvent('foundLocation', loc);
				return;
			}
			else if(values.provincie) {
				var loc = {
					boundingBox: location.provincie.boundingBox,
					type: 'Provincie',
					name: location.provincie.naam
				};
				parent.fireEvent('foundLocation', loc);
				return;
			}
			else {
				// Apparently nothing is selected
				Ext.Msg.alert(messages.msg.titleError(), messages.searchLocationPanel.selectCriteria());
				return;
			}
		}

		// Get to here if a special search (postcode or straatnaam with huisnummer) is necessary
		parent.adresStore.load({
			params: {
				query: params
			}
			,'callback': function(record, options, success) {

				if (success && record[0]) {

					var loc = {
						boundingBox: record[0].json.boundingBox,
						name: record[0].json.straatnaam,
						parent: record[0].json.woonplaats,
						type: 'Straat'
					};

					var panel = Ext.getCmp('searchLocationPanel');
					panel.straatCombo.setRawValue(loc.name);
					panel.woonplaatsCombo.setRawValue(loc.parent);

					// format for display in further events
					loc.name = record[0].json.straatnaam + (record[0].json.huisnummer != null ? ' ' +record[0].json.huisnummer : '')
						+ ', ' + record[0].json.woonplaats;
					if(options.params.query[0].postcode) {
						loc.name = loc.name + ' (' +options.params.query[0].postcode+ ')';
					}

					panel.fireEvent('foundLocation', loc);
				} else {
					Ext.Msg.alert(messages.msg.titleError(), messages.searchLocationPanel.noAddressFound());
				}
			}
		});

	}
	,onClear : function() {
		this.getForm().reset();
	}

});	// e/o extend

// register xtype
Ext.reg('searchLocationPanel', Roo.gui.SearchLocationPanel);
// }}}