/**
 * Implement the search form handling.
 * 
 * ----
 * 
 * LICENCE
 * 
 * This work is licensed under Creative Commons Attribution-Share Alike 3.0 (Germany).
 * For details on this licence visit http://creativecommons.org/licenses/by-sa/3.0/de/
 * 
 * All rights reserved
 * 
 * @author Jakob Hohlfeld | http://www.netronaut.de
 * @copyright 2010 by Jakob Hohlfeld
 * 
 */
var Minisearch_Form = new Class
({
	Extends: NetronautUI_Widget,
	
	data: {},
	
	result_window: null,
	date_from: null,
	date_to: null,
	optionsDialogue: null,
	
	/**
	 * The constructor.
	 * 
	 * Options:
	 * 	- data A data provider to store the search form data in.
	 *  - render A function implementing the rendering. This function must declare the needed form elements date_from, date_to and guests.
	 * 
	 * @param HTMLElement el
	 * @param object options
	 */
	initialize: function ( el, options ) {
		if(options.render) {
			this.render = options.render.bind(this);
			delete options.render;
		}
		
		this.parent(el, options);
		this.data = options.data;
		this.update();
		
		// submit
		this.dom.el.getElement('form').addEvent('submit', function(event){
			new Event(event).stop();
			this.submit(event.target.action);
		}.bind(this));
		
		// location
		if(this.dom.search) {
			this.dom.search.addEvent('focus', function(){
				this.select();
			});
		}
		
		// date picker
		this.date_from.calendar.setLimit({from: new Date()});
		this.date_to.calendar.setLimit({from:this.date_from.calendar.getDate().clone().increment('day', 1)});
		this.date_from.addEvent('update', function(date){
			if((d=new Date().clearTime()).diff(date) < 0) {
				this.date_from.update(d);
				return;
			}
			var diff = new Date(this.data.options.dates.arrival).diff(new Date(this.data.options.dates.departure));
			this.data.options.dates.arrival = date.getTime();
			this.date_to.calendar.setLimit({from:date.clone().increment('day', 1)});
			date = date.clone().increment('day', diff);
			this.date_to.update(date);
			this.data.options.dates.departure = date.getTime();
			this.data.write()
		}.bind(this));
		this.date_to.addEvent('update', function(date){
			var date_from = new Date(this.data.options.dates.arrival);
			var diff = date_from.diff(new Date(this.data.options.dates.departure));
			if(date_from.diff(date) < 1) {
				date = date_from.clone().increment('day', diff);
				this.date_to.update(date);
			}
			this.data.options.dates.departure = date.getTime();
			this.data.write()
		}.bind(this));
		this.dom.hitarea.extend(this.date_from.dom.hitarea);
		this.dom.hitarea.extend(this.date_to.dom.hitarea);
		
		var winOptions = {'positionOnTarget':true, 'autoClose':true, 'position':'absolute', 'alwaysInView':true};
		
		// guests dialogue
		var widget_options = new Minisearch_FormOptions();
		var win_guests = new NetronautUI_Window(widget_options, winOptions).setSize({x:640});
		widget_options.addEvent('save', win_guests.close.bind(win_guests));
		widget_options.addEvent('cancel', win_guests.close.bind(win_guests));
		this.dom.hitarea.extend(win_guests.dom.hitarea);
		this.optionsDialogue = win_guests;
		
		// ~open
		this.addEvent('guestDetailSelected', function ( event ) {
			win_guests.open(new Event(event).stop());
			win_guests.dom.object.dom.el.getElements('fieldset')[event.target==this.dom.guests.getElement('a')?0:1].getElement('input').select();
		});
		win_guests.addEvent('beforeOpen', function () {
			widget_options.setData(this.data.options);
		}.bind(this)).addEvent('open', function () {
			this.dom.el.getElement('input').select();
		});
		
		// ~save
		widget_options.addEvent('save', function () {
			this.data.options.extend(widget_options.getData());
			this.data.write();
			this.update();
		}.bind(this));
		
		// 
		// categories selector -
		//   create behaviour of the category checkboxes
		//
		var elements;
		if(elements = this.dom.category) {
			
			// init: (re)activate checkboxes
			elements.each(function(el){
				if(!this.data.options.category) return;
				el.checked = this.data.options.category.contains(el.value);
			}.bind(this));
			
			// onclick: update search data
			var update = function( item ) {
				if(item == elements.getLast() && item.checked) {
					elements.each(function(el){
						if(el == elements.getLast()) return;
						el.checked = false;
					});
				} else {
					elements.getLast().checked = false;
				}
				this.data.options.category = [];
				elements.each(function(el){
					if(!el.checked) return;
					this.data.options.category.combine(el.value);
				}.bind(this));
				this.data.write();
			}.bind(this);
			elements.each(function(el){
				el.addEvent('click', update.pass(el));
			}.bind(this));
		}
	},
	
	/**
	 * Submit data - Aggregate the data needed and view the result in an iframe.
	 * 
	 */
	submit: function ( url ) {
		if(!this.result_window) {
			var iframe = new NetronautUI_Widgets_Iframe(null, {name: 'search_result'});
			this.result_window = new NetronautUI_Window(iframe, {autoClose:true, addOverlay:true});
			new NetronautUI_WindowDecorator(this.result_window, {'closeButton':{events:{'click':this.result_window.close.bind(this.result_window)}, 'offset':{x:-8, y:6}}});
			var windowOnResize = function(){
				this.setSize({
					x: document.getSize().x*0.85,
					y: document.getSize().y*0.85
				});
				this.setPosition({
					x: (window.getSize().x-this.getSize().x)/2,
					y: (window.getSize().y-this.getSize().y)/2
				});
			}.bind(this.result_window);
			this.result_window.addEvent('beforeOpen', windowOnResize)
			.addEvent('open', window.addEvent.pass(['resize', windowOnResize], window))
			.addEvent('close', window.removeEvent.pass(['resize', windowOnResize], window));
		} else {
			var iframe = this.result_window.dom.object;
		}
		
		// submit
		if(this.dom.search) {
			this.data.options.location = this.dom.search.value;
			this.data.write();
		}
		
		// add object_id
		var proxy_url = '/search/provider/wildeast/';
		if((m = url.match(/objekt\[\]=(\d+)/)) && m[1]) {
			proxy_url += 'object_id/'+m[1]+'/';
		}
		
		// submit request
		iframe.load(proxy_url);
		this.result_window.open();
	},
	
	/**
	 * Render the component.
	 * 
	 */
	render: function () {
		this.dom.form = this.dom.el.getElement('form');
		this.dom.search = this.dom.form.getElement('input[name=ort_name]');
		this.date_from = new NetronautUI_Widgets_InputDate(this.dom.form.getElement('[name=date_from]'));
		this.date_to = new NetronautUI_Widgets_InputDate(this.dom.form.getElement('[name=date_to]'));
		this.dom.el.getElement('.option-guests').empty().adopt(
			this.dom.guests = new Element('div'),
			this.dom.options_icons = new Element('p'),
			new Element('div').adopt(
				new Element('a', {'class':'light', href:'javascript:void(0);', text:'Suche anpassen'})
					.addEvent('click', function(event){this.fireEvent('guestDetailSelected', event)}.bind(this))
			)
		);
		this.dom.category = this.dom.form.getElements('.option-category')[0].getElements('input');
	},
	
	/**
	 * Update this widgets components.
	 * 
	 * This method transfers valuies from the cookie domain into the widget components.
	 * 
	 * @return self
	 */
	update: function () {
		
		// dates
		this.date_from.update(new Date(this.data.options.dates.arrival));
		this.date_to.update(new Date(this.data.options.dates.departure));

		// update details
		this.updateGuestDetail(this.data.options.persons);
		
		// options icons
		if(!this.dom.options_icons) return this;
		var open_icon_option = function(event){
			this.optionsDialogue.open(event.stop())
			this.optionsDialogue.dom.el.getElements('fieldset')[2].getElement('input').select();
		}.bind(this);
		this.dom.options_icons.empty();
		new Hash({
			'max_price':'Maximaler Tagespreis %max_price%€',
			'max_beach_distance':'Maximale Entfernung zum Strand %max_beach_distance%km',
			'pets_allowed':'Haustiere erlaubt'
		}).each(function(text, opt){
			if(!(value = this.data.options.options[opt])) return;
			new Element('button', {
				'class':'minisearch-form-options-icon-'+opt,
				title: text.replace(new RegExp('%'+opt+'%'), this.data.options.options[opt]), 
				events:{'click':open_icon_option}
			}).inject(this.dom.options_icons);
		}.bind(this));
		if(null!=(value=this.data.options.options.smoking)) {
			var opt = (this.data.options.options.smoking?'':'no')+'smoking';
			new Element('button', {
				'class':'minisearch-form-options-icon-'+opt,
				title: opt=='smoking'?'Raucher':'Nichtraucher', 
				events:{'click':open_icon_option}
			}).inject(this.dom.options_icons);
		}
		
		return this;
	},
	
	/**
	 * Update guest detail display.
	 * 
	 * @param object data Person data derived from SearchData
	 */
	updateGuestDetail: function ( data ) {
		
		// handle adults
		this.dom.guests.innerHTML = '';
		var num_adults = Number(data.adults);
		if(!num_adults && (!data.children || !data.children.length)) {
			num_adults = 1;
		}
		if(num_adults > 0) {
			var a = new Element('a', {
				href: 'javascript:void(0);',
				html: num_adults + ' Erwachsen' + (num_adults==1?'er':'e')
			});
			a.inject(this.dom.guests).addEvent('click', function( event ) {
				this.fireEvent('guestDetailSelected', event);
			}.bind(this));
		}
		new Element('br').inject(this.dom.guests);
		
		// children
		// event handler for click on child label
		var child_open = function (event) {
				this.fireEvent('guestDetailSelected', event);
			}.bind(this);
		
		// make a routine for adding children
		var addChild = function (child) {
			new Element('a', {
				href: 'javascript:void(0);',
				html: childText(child)
			}).addEvent('click', child_open).inject(this.dom.guests);
		}.bind(this);
		
		// child text describing number and age of child
		var childText = function(child) {
			return (child && child.count>0 ?child.count :'kein') + ' Kind' + (child&&child.count>1 ?'er':'') + (child&&child.count>0 ?' (' + child.age + ')' :'');
		}
		
		// add first age group of children
		if(!data.children.length) {
			addChild(null);
			return;
		}
		addChild(data.children[0]);
		
		// are there other children?
		if(data.children.length>1) {
			var text = [];
			for(var i=1; i<data.children.length; i++) {
				text.push(childText(data.children[i]));
			}
			this.dom.guests.appendChild(document.createTextNode(', '));
			new Element('a', {
				href:'javascript:void(0);', 
				text:'[..]', 
				title:(text.length>1?text.length+' weitere Kinder: ':'') + text.join(', '), 
				events:{'click':child_open}
			}).inject(this.dom.guests);
		}
	}
});

