var SearchForm = new Class({
	Implements: [Options, Events, Log],

	// Constants
	SUBMIT_DELAY: 250,

	// Variables
	element: null,
	form: null,
	application: null,
	resultContainer: null,
	keyTimer: null,
	query: "",
	moreResultPath: null,
	isRunning: false,


	// Class instances
	
	initialize: function( element )
	{
		//this.enableLog();
		//this.disableLog();
		this.log("SearchForm::initialize()");

		// Set variables
		this.element = element;
		this.application = new Application();
		this.moreResultPath = this.application.getConfig().requestPath.search.more;

		this.initForm();
	},

	/*
	 * Init form
	 */
	initForm: function()
	{
		this.log("SearchForm::initForm()");

		var requestUrl = this.application.getConfig().requestPath.search.result;

		var handlers = {
			onRequest: function()
			{
				this.log("onRequest");

				this.isRunning = true;
				this.form.element.addClass('loading');

			}.bind(this),
			onSuccess: function(response)
			{
				this.log("onSuccess: "+ response.success);

				for(var i in response)
				{
					this.log("response[" + i + "]: " + response[i]);
				}

				this.isRunning = false;
				this.form.element.removeClass('loading');

				var result;
				if(response.success)
				{
					//this.log("succes!");
					result = response.result;
					
					// Track event
					this.application.trackEvent('search', 'success', this.application.page.name, result.length);
				}
				else
				{
					//this.log("error!");
					result = {};
					
					// Track event
					this.application.trackEvent('search', 'error', this.application.page.name);
				}

				this.buildResult(result);
				this.showResult();
				
			}.bind(this),
			onFailure: function(xhr)
			{
				this.log("onFailure");
				
				this.isRunning = false;
				this.form.element.removeClass('loading');
				
				// Track event
				this.application.trackEvent('search', 'fail', this.application.page.name);
			}.bind(this)
		};

		var options = {
			showLoader: true,
			formErrorMessage: {
				allow: false
			}
		};

		var searchOptions = {};
		searchOptions.hintText = "Zoeken..";
		searchOptions.submitOnEnter = false;

		var form = new JsonForm($('search-form'), requestUrl, handlers, options);
		
		var searchElement = new FormElement(form, 'q', searchOptions);
		form.addElement(searchElement);

		searchElement.element.addEvents({
			'focus': function(event) {
				//this.log("focus");

				searchElement.element.addEvent('keydown', function(event) {

					if(event.key == 'tab')
					{
						this.log("tab keydown");
						this.hideResult();
					}
					else if(event.key == 'enter')
					{
						var searchUrl = this.createSearchUrl(this.query);
						this.log("searchUrl: "+ searchUrl);

						// Set location
						var location = searchUrl.toURI();
						location.go();
					}

				}.bind(this));

				if(searchElement.element.value.length > 0)
				{
					if(this.query.length > 0)
					{
						this.showResult();
					}
					else
					{
						this.submit(searchElement.element.value);
					}
				}
			}.bind(this),

			'blur': function(event) {
				//this.log("blur");

				searchElement.element.removeEvents('keydown');
			}.bind(this),

			'keyup': function(event) {

				this.log("keyup: " + event.key);

				if(event.key == 'enter')
				{
					return;
				}

				if(searchElement.element.value.length > 0)
				{
					this.keyTimer = clearTimeout(this.keyTimer);
					this.keyTimer = this.submit.delay(this.SUBMIT_DELAY, this, [searchElement.element.value]);
				}
				else
				{
					this.query = searchElement.element.value;
					this.hideResult();
				}

			}.bind(this)

		});

		// Save form
		this.form = form;
		
		this.form.addEvent('onSubmit', function() {

			this.log("onSubmit");
			
			// Track event
			this.application.trackEvent('search', 'submit', this.application.page.name);

		}.bind(this));

		// Submit button
		var submitButton = new Element('a', {'href': '#', 'class': 'submit'});
		this.form.element.getElement('fieldset').adopt(submitButton);
		submitButton.addEvent('click', function(event) {
			event.preventDefault();

			var searchUrl = this.createSearchUrl(this.query);
			this.log("searchUrl: "+ searchUrl);

			// Set location
			var location = searchUrl.toURI();
			location.go();
		}.bind(this));

		// Result container
		this.resultContainer = new Element('div', {'class': 'search-results'});
		this.resultContainer.fx = new Fx.Tween(this.resultContainer, {
			duration: 250,
			transition: Fx.Transitions.Quad.easeOut,
			property: 'opacity',
			link: 'cancel'
		});
		this.resultContainer.fx.set(0);

		this.resultContainer.fx.addEvent('start', function() {

			if(this.resultContainer.getStyle('opacity').toInt() == 0)
			{
				this.resultContainer.show();
			}
		}.bind(this));

		this.resultContainer.fx.addEvent('complete', function() {

			if(this.resultContainer.getStyle('opacity').toInt() == 0)
			{
				this.resultContainer.hide();
			}
		}.bind(this));
	   
		$('website').adopt(this.resultContainer);

		$(window).addEvent('click', function(event) {

//			this.log("document clicked!");
//			this.log("event.target: " + event.target);
//			this.log("event.target.get('class'): " + event.target.get('class'));
//			this.log("$(event.target).getParents(): " + $(event.target).getParents());
//			this.log("$(event.target).getParents().contains(this.resultContainer): " + $(event.target).getParents().contains(this.resultContainer));

//			$(event.target).getParents().each(function(parent) {
//				this.log("parent: "+ parent);
//				this.log("parent.class: "+ parent.get('class'));
//
//			}.bind(this));

			if(this.resultContainer && !event.target ||
				!$(event.target).getParents().contains(this.resultContainer)) {
				
				if(	$(event.target) == searchElement.element ||
					$(event.target).getParents().contains(this.element.getElement('.search')) ||
					$(event.target).getParents().contains(this.element.getElement('.contact')))
				{
					return;
				}

				this.cancel();
				this.hideResult();
			}

		}.bind(this));
	},

	submit: function(query)
	{
		this.log("SearchForm::submit(" + query + ")");

		if(this.query != query)
		{
			this.query = query;
			this.form.submit();
		}
	},

	cancel: function()
	{
		this.log("SearchForm::cancel()");

		if(this.isRunning && 
			this.application.jsonRequest &&
			this.application.jsonRequest.isRunning())
		{
			this.query = "";
			this.form.element.removeClass('loading');
			this.form.cancel();
		}
	},

	buildResult: function(data)
	{
		this.log("SearchForm::buildResult(" + data + ")");

		var programme = (data.programme) ? data.programme : [];
		var afterglow = (data.afterglow) ? data.afterglow : [];
		var news = (data.news) ? data.news : [];
		var pages = (data.pages) ? data.pages : [];

//		this.log("programme.length: "+ programme.length);
//		this.log("afterglow.length: "+ afterglow.length);
//		this.log("news.length: "+ news.length);
//		this.log("pages.length: "+ pages.length);

		// Build result
		this.resultContainer.empty();

		if(programme.length > 0 || afterglow.length > 0 || news.length > 0 || pages.length > 0)
		{
			var results = new Element('div', {'class': 'results'});
			var amountText;
			var category;
			var header;
			var list;

			// Body
			var body = new Element('div', {'class': 'body'});

			var footer = new Element('div', {'class': 'footer'});
			var searchUrl = this.createSearchUrl(this.query);
			this.log("searchUrl: " + searchUrl);
			var showResults = new Element('a', {'href': searchUrl, 'text': 'Bekijk alle resultaten', 'class': 'button show-results'});
			showResults.addEvent('click', function() {
				
				// Track event
				this.application.trackEvent('search', 'show results - click', this.application.page.name);

			}.bind(this));
			
			footer.adopt(showResults);


			// Programme
			if(programme.length > 0)
			{
				amountText = this.getResultAmountText(programme.length);

				category = new Element('div', {'class': 'category programme'});
				if(!afterglow.length) category.addClass('last-child');

				header = new Element('div', {'class': 'header'});
				header.adopt( new Element('h3', {'text': 'Programma', 'class': 'title'}) );
				header.adopt( new Element('div', {'text': amountText, 'class': 'amount'}) );
				category.adopt(header);

				list = new Element('ul');
				programme.each(function(item, index) {

					var listElement = new Element('li');
					var link = new Element('a', {'href': item.url, 'title': item.title.main.stripTags()});
					listElement.adopt(link);

					var title = new Element('span', {'class': 'title'});
					title.adopt( new Element('span', {'text': item.date.day + ' ' + item.date.date, 'class': 'date'}) );
					title.adopt( new Element('span', {'text': item.title.main.stripTags(), 'class': 'main'}) );
					if(item.title.support) title.adopt( new Element('span', {'text': item.title.support.stripTags(), 'class': 'support'}) );
					link.adopt(title);

					var info = new Element('span', {'html': '<span class="venue">' + item.venue + '</span> / <span class="time">' + item.start_time + '</span>', 'class': 'info'});
//					info.adopt( new Element('span', {'text': item.venue, 'class': 'venue'}) );
//					info.adopt( new Element('span', {'text': item.start_time, 'class': 'time'}) );
					link.adopt(info);
					
					list.adopt(listElement);

					// Init event item
					var eventItem = new EventItem(listElement);

				}.bind(this));
				category.adopt(list);

				body.adopt(category);
			}

			// Afterglow
			if(afterglow.length > 0)
			{
				amountText = this.getResultAmountText(afterglow.length);

				category = new Element('div', {'class': 'category afterglow'});
				if(!news.length) category.addClass('last-child');

				header = new Element('div', {'class': 'header'});
				header.adopt( new Element('h3', {'text': 'Nagenieten', 'class': 'title'}) );
				header.adopt( new Element('div', {'text': amountText, 'class': 'amount'}) );
				category.adopt(header);

				list = new Element('ul');
				afterglow.each(function(item, index) {

					var listElement = new Element('li');
					var link = new Element('a', {'href': item.url, 'title': item.title.main});
					listElement.adopt(link);

					link.adopt( new Element('img', {'src': item.image, 'width': '50', 'width': '50', 'title': item.title.main.stripTags(), 'alt': item.title.main.stripTags()}) );

					var info = new Element('span', {'class': 'info'});
					info.adopt( new Element('span', {'text': item.title.main.stripTags(), 'class': 'main'}) );
					info.adopt( new Element('span', {'text': item.date, 'class': 'date'}) );
					link.adopt(info);

					list.adopt(listElement);

					// Init event item
					var eventItem = new EventItem(listElement);

				}.bind(this));
				category.adopt(list);

				body.adopt(category);
			}

			// News
			if(news.length > 0)
			{
				amountText = this.getResultAmountText(news.length);

				category = new Element('div', {'class': 'category news'});
				if(!pages.length) category.addClass('last-child');

				header = new Element('div', {'class': 'header'});
				header.adopt( new Element('h3', {'text': 'Nieuws', 'class': 'title'}) );
				header.adopt( new Element('div', {'text': amountText, 'class': 'amount'}) );
				category.adopt(header);

				list = new Element('ul');
				news.each(function(item, index) {

					var listElement = new Element('li');
					var link = new Element('a', {'href': item.url, 'title': item.title.stripTags()});
					listElement.adopt(link);

					link.adopt( new Element('span', {'html': item.title.stripTags(), 'class': 'title'}) );
					link.adopt( new Element('span', {'html': item.description.stripTags(), 'class': 'description'}) );
					link.adopt( new Element('span', {'text': item.date, 'class': 'date'}) );
					list.adopt(listElement);

				}.bind(this));
				category.adopt(list);

				body.adopt(category);
			}
			
			// Pages
			if(pages.length > 0)
			{
				amountText = this.getResultAmountText(pages.length);

				category = new Element('div', {'class': 'category pages'});
				category.addClass('last-child');

				header = new Element('div', {'class': 'header'});
				header.adopt( new Element('h3', {'text': "Pagina's", 'class': 'title'}) );
				header.adopt( new Element('div', {'text': amountText, 'class': 'amount'}) );
				category.adopt(header);

				list = new Element('ul');
				pages.each(function(item, index) {

					var listElement = new Element('li');
					var link = new Element('a', {'href': item.url, 'title': item.title.stripTags()});
					listElement.adopt(link);

					link.adopt( new Element('span', {'class': 'icon'}) );
					link.adopt( new Element('span', {'html': item.title.stripTags(), 'class': 'title'}) );
					list.adopt(listElement);

				}.bind(this));
				category.adopt(list);
				
				body.adopt(category);
			}

			// Adopt results
			results.adopt(body);
			results.adopt(footer);
			this.resultContainer.adopt(results);

		}
		else
		{
			var noResults = new Element('div', {'class': 'no-results'});
			noResults.adopt( new Element('p', {'text': 'Helaas, er zijn geen resultaten gevonden.'}) );
			noResults.adopt( new Element('p', {'text': 'Pas je zoekopdracht aan en probeer het nog eens.'}) );
			this.resultContainer.adopt(noResults);
		}

		// Show
		this.resultContainer.fx.start(1);
	},

	showResult: function()
	{
		//this.log("SearchForm::showResult()");

		this.resultContainer.fx.start(1);
	},

	hideResult: function()
	{
		//this.log("SearchForm::hideResult()");

		this.resultContainer.fx.start(0);
	},

	createSearchUrl: function(query)
	{
		this.log("SearchForm::createSearchUrl(" + query + ")");

		var url = this.moreResultPath + '?q=' + encodeURIComponent(query);

		return url;
	},

	getResultAmountText: function(amount)
	{
		//this.log("SearchForm::getResultAmountText(" + amount + ")");

		var text;
		if(amount === 1)
		{
			text = amount + " resultaat";
		}
		else
		{
			text = amount + " resultaten";
		}

		return text;
	}

});
