/*
 * Copyright 2008-2009 Palm, Inc. All rights reserved.
 */
/*global Mojo, Class, $L, AddressBar, UrlBar, UrlSearchController, window */
/*jslint rhino:true, undef:true */

AddressBar = Class.create({

	initialize: function(controller) {
	
		this._controller = controller;
		this._urlBar = new UrlBar(this._controller);
		this._urlSearch = new UrlSearchController(this._controller);
		this._hideTimeout = 0.50;		

		this._invalidFilters = ['ht', 'htt', 'http', 'http:', 'http:/', 'http://'];
	},
	
	setup: function(params) {

		// A filter function to allow a cleaner callback function
		var onFilteredPropertyChange = function(propertyChangeEvent) {
			
			// Take whatever was typed and strip whitespace from either
			// end of the string before passing onto the application and
			// search engines.
			var url = propertyChangeEvent.value;			
			url = url && url.strip();
			var value = {
				value: url,
				type: 'unknown'
			};
			
			if (propertyChangeEvent.originalEvent && propertyChangeEvent.originalEvent.keyCode) {
				
				value.type = 'keyCode';
				value.keyCode =  propertyChangeEvent.originalEvent.keyCode;
				if (propertyChangeEvent.originalEvent.keyCode !== Mojo.Char.enter) {
					if (this.isValidFilterText(url)) {
						this.openSearchResults(url);
					} else {
						this.closeSearchResults();
					}
				}
			} else if (propertyChangeEvent.type === 'blur') {
				
				value.type = 'blur';
			} else if (propertyChangeEvent.type === 'mojo-property-change') {
				
				value.type = 'mojo-property-change';
				if (this.isValidFilterText(url)) {
					this.openSearchResults(url);
				} else {
					this.closeSearchResults();
				}
			}
			
			// Forward onto the caller.			
			params.onPropertyChange(value);
		}.bind(this);

		// Initialize the URL bar and search controllers with
		// the filters versions of the callbacks.
		this._urlBar.setup({
			onPropertyChange: onFilteredPropertyChange,
			orientation: params.orientation,
			visible: params.visible
		});
		
		// Setup the url search controller.
		this._urlSearch.setup({
			onSelect: params.onSelect,
			onEnableSceneScroller: params.onEnableSceneScroller
		});		
	},
	
	isValidFilterText: function(url) {

		if (url === null || url.length < 2) {
			return false;
		}
		
		url = url.toLowerCase();
		if (this._invalidFilters.indexOf(url) !== -1) {
			return false;
		}
		
		return true;	
	},
	
	startObserving: function() {
		
		this._urlBar.startObserving();
	},
	
	stopObserving: function() {
		this._urlBar.stopObserving();
	},
	
	cleanup: function() {
		this._urlBar.cleanup();	
		this._urlSearch.cleanup();
	},
	
	getValue: function() {
	
		return this._urlBar.getValue();
	},
	
	hasFocus: function() {
	
		return this._urlBar.hasFocus();
	},
	
	focus: function() {
		
		this._urlBar.focus();
	},
	
	blur: function() {
		
		this._urlBar.blur();
	},
	
	select: function() {
		
		this._urlBar.select();
	},

	setAddressAndTitle: function(address, title) {
		
		this._urlBar.setTitle(title);
		this._urlBar.setUrl(address);
	},
	
	enableTitleView: function() {
		
		this._urlBar.enableTitleView();
	},
	
	enableUrlView: function() {
		
		this._urlBar.enableUrlView();
	},
	
	show: function() {
		
		if (this._hideTimerId) {
			// Clear any timeout for hide. 
			window.clearTimeout(this._hideTimerId);
			// Remove the masking 'hide' function.
			delete this.hide;
			delete this._hideTimerId;
		}

		this._urlBar.show();
	},
	
	isVisible: function() {
		
		return this._urlBar.isVisible();
	},
	
	isInUrlView: function() {
		
		return this._urlBar.isInUrlMode();
	},
	
	hide: function() {
		
		// We are being called so let's mask the hide until
		// we've completed the delayed hide call.
		this.hide = function() {};
		
		// Once the timer is fired then determine what we should
		// actually do
		var hideCallback = function() {

			// Hide both the URL bar and the search list.
			if (!this._urlBar.hasFocus()) {
				this.closeSearchResults();
				this._urlBar.hide();
			}

			// Completed the callback so we remove the masked 'hide'.
			delete this._hideTimerId;
			delete this.hide;
		}.bind(this);
			
		this._hideTimerId = hideCallback.bind(this).delay(this._hideTimeout);
	},
	
	closeSearchResults: function() {
		
		this._clearUrlTypeDelay();
		this._urlSearch.hideSearchList();
	},
	
	openSearchResults: function(url) {
		
		this._clearUrlTypeDelay();
		this._urlSearch.showSearchList();
		this._updateSearchResults(url);
	},
	
	convertInputToUrl: function(url) {
		
		return this._urlSearch.getDefaultUrl(url);
	},
	
	areSearchResultsVisible: function() {
	
		return this._urlSearch.isSearchListVisible();
	},
	
	isAGotoAddressBarEvent: function(event) {
		
		return this._urlBar.isAGotoUrlBarKey(event.keyCode);
	},

	setOrientation: function(orientation) {
		
		this._urlBar.setOrientation(orientation);
		if (orientation !== 'up') {
			this.closeSearchResults();
		}
	},
	
	_clearUrlTypeDelay: function() {
		
		if (this._urlSearchTypeDelayId) {
			window.clearTimeout(this._urlSearchTypeDelayId);
			delete this._urlSearchTypeDelayId;
		}
	},
	
	_updateSearchResults: function(url) {
		
		// Should provide sources of data ?
		this._urlSearchTypeDelayId = this._urlSearch.startFillingList.bind(this._urlSearch).delay(0.25, url);
	},
	
	enableSSLLock: function(enable) {
		this._urlBar.enableSSLLock(enable);	
	}
});

AddressBar.defaultHintText = UrlBar.defaultHintText;
