/**
 * @filename SearchBarHandler.js
 * 
 * @description Handles events for search bar
 * 
 * @author Diana Chow
 * @email diana.chow@garmin.com
 * @author Devon Lindsey
 * @email devon.lindsey@garmin.com
 *
 * @requires Prototype 1.6.0.2+
 * 
 * Copyright(c) 2008, Garmin International
 */

if(Garmin == undefined) var Garmin = {};

/**
 * SearchBarHandlerConstants provides id's and classes used for generated elements created
 * within the SearchBarHandler object.
 * 
 */
var SearchBarHandlerConstants = {
    // IDs
	SEARCH_PROGRESS: 'searchButtonProgress',
	CURRENT_PAGE_ID: 'currentPage',
	SORT_FIELD_ID: 'exploreSearchForm:sortField',
	KEYWORD_ID: 'exploreSearchForm:keyword',
	LOCATION_ID: 'exploreSearchForm:location',
    ACTIVITY_TYPE_SELECT_ID: 'exploreSearchForm:activityType',
    EVENT_TYPE_SELECT_ID: 'exploreSearchForm:eventType',
    FILTERS_BOX_ID: 'filtersBox',
    SEARCH_BOX_ID: 'searchBox',
    SHOW_FILTERS_ID: 'showFilters',
    HIDE_FILTERS_ID: 'hideFilters',
    USERNAME_ID: 'exploreSearchForm:username',
    MY_ACTIVITIES_ID: 'exploreSearchForm:myActivities',
    SEARCH_BUTTON: 'searchButton',
    TIME_SELECT_ID: 'exploreSearchForm:timePeriodSelect',
    MIN_DISTANCE_ID: 'exploreSearchForm:minDistance',
    MAX_DISTANCE_ID: 'exploreSearchForm:maxDistance',
    MIN_TIME_ID: 'exploreSearchForm:minTime',
    MAX_TIME_ID: 'exploreSearchForm:maxTime',
    MIN_ELEVATION_ID: 'exploreSearchForm:minElevation',
    MAX_ELEVATION_ID: 'exploreSearchForm:maxElevation',
    REAL_SEARCH_BUTTON: 'exploreSearchForm:realSearchButton',
    CUSTOM_DATES_ID: 'customDates',
    START_ID: 'exploreSearchForm:startDateCalendarInputDate',
    END_ID: 'exploreSearchForm:endDateCalendarInputDate',
    DISTANCE_UNIT: 'exploreSearchForm:distanceUnitValue',
    TIME_UNIT: 'exploreSearchForm:timeUnitValue',
    ELEVATION_UNIT: 'exploreSearchForm:elevationUnitValue',
    DISTANCE_HTML: 'distanceHtml',
    TIME_HTML: 'timeHtml',
    ELEVATION_HTML: 'elevationHtml',
    MAX_LAT_ID: 'exploreSearchForm:bbMaxLat',
    MAX_LON_ID: 'exploreSearchForm:bbMaxLong',
    MIN_LAT_ID: 'exploreSearchForm:bbMinLat',
    MIN_LON_ID: 'exploreSearchForm:bbMinLong',
    CURRENT_MAP_VIEW_ID: 'currentMapView',
    GLOBAL_SEARCH: 'globalSearch',
    
    // Class
    ADVANCED_OPTION_FIELD_CLASS: 'advancedOptionsField',
    ADVANCED_SEARCH_CLASS: 'searchBoxAdvanced',
    SEARCH_CLASS: 'searchBox',
	SHOW_FILTERS_CLASS: 'advancedSearchTrigger',
	DISABLED: 'disabled',
	
	BUSINESS_KEYS: {
	    activityTypeAll: 'all'
	}
};

/**
 * The SearchBarHandler class generates the view and provides functions for altering the
 * view.
 * 
 * @constructor
 */
Garmin.SearchBarHandler = Class.create({
	
    initialize: function() {		
        this.searchBox = $(SearchBarHandlerConstants.SEARCH_BOX_ID);
        this.showFilterButton = $(SearchBarHandlerConstants.SHOW_FILTERS_ID);
        this.hideFilterButton = $(SearchBarHandlerConstants.HIDE_FILTERS_ID);
        this.clearFields;
        this.displayStart = false;
        this.displayEnd = false;
        this.displayCustom;
        this.filtersBox = $(SearchBarHandlerConstants.FILTERS_BOX_ID);
        //refreshes the page when the timeout happens so that the user
		//will never see the 500
        resetSessionTimeoutCheck();        
        this.setEventHandlers();
		this.hideSearchProgress();
//        this.setInputHandlers();
    },
    
    /**
     * Sets handlers for events made by the user on the UI 
     */
    setEventHandlers: function() {    	
    	var all = $(SearchBarHandlerConstants.USERNAME_ID);
		var mine = $(SearchBarHandlerConstants.MY_ACTIVITIES_ID);
    	var event = $(SearchBarHandlerConstants.EVENT_TYPE_SELECT_ID);
    	var time = $(SearchBarHandlerConstants.TIME_SELECT_ID);
    	var start = $(SearchBarHandlerConstants.START_ID);
    	var end = $(SearchBarHandlerConstants.END_ID);
    	
        this.showFilterButton.onclick = function() {
            this.showFilters();
            this.clearFields = false;
        }.bind(this);        		    	
    	
        this.hideFilterButton.onclick = function() {
            this.hideFilters();
            this.clearFields = true;
            //clears out the advanced filters option when the hide filters is clicked and a new 
            //search is performed
            $(SearchBarHandlerConstants.SEARCH_BUTTON).onclick = function() {
            	if (this.clearFields == true) {
                	this.resetFilters();
                	this.resetCurrentPage();
            	}
            	
            	this.clickSearch();
            }.bind(this);
        }.bind(this);
        
       //toggling between searching my activities only, and searching other users activities
        if (mine != null) {
        	all.onchange = function() {
        		//resets checkbox to normal when there's no text in input field
        		if (all.value == "" && (mine.getAttribute(SearchBarHandlerConstants.DISABLED) != null)) {
        			this.enable(mine, $('myField'))
        		//disables checkbox when there is text in input field
        		} else {
        			this.disable(mine, $('myField'));
        		}
        	}.bind(this);
        	
        	mine.onchange = function() {
        		//resets input field to normal when checkbox is not selected
        		if (mine.checked == false && (all.getAttribute(SearchBarHandlerConstants.DISABLED) != null)) {
        			this.enable(all, $('usernameField'))
        		//disables input field when checkbox is selected
        		} else {
        			this.disable(all, $('usernameField'));
        		}
        	}.bind(this);
        };
        
        //displays the custom date filters when the user selects the option
        time.onchange = function() {
        	if (time.value == 'customTimestamp') {
        		$(SearchBarHandlerConstants.CUSTOM_DATES_ID).show();
        	} else {
        		if ($(SearchBarHandlerConstants.CUSTOM_DATES_ID).visible()) {
        			$(SearchBarHandlerConstants.CUSTOM_DATES_ID).hide();
        			start.setValue("");
	            	end.setValue("");
        		}
        	}
        };
        
        //populates unit type input fields to submit to the service
        $(SearchBarHandlerConstants.DISTANCE_UNIT).setValue($(SearchBarHandlerConstants.DISTANCE_HTML).innerHTML);
        $(SearchBarHandlerConstants.TIME_UNIT).setValue($(SearchBarHandlerConstants.TIME_HTML).innerHTML);
        $(SearchBarHandlerConstants.ELEVATION_UNIT).setValue($(SearchBarHandlerConstants.ELEVATION_HTML).innerHTML);
        
        //capture enter key press.  There's two because the event is different
        //for ie
        if (document.addEventListener){
			document.addEventListener('keypress', function(event) {
				if(event.keyCode == Event.KEY_RETURN){
					if (searchBarHandler.clearFields == true) {
	                	searchBarHandler.resetFilters();
	                	searchBarHandler.resetCurrentPage();
	            	}
					searchBarHandler.clickSearch();
					//Stops page refresh in safari.  totally whacky hacky.  
					//Just the way i like it.
					Event.stop(event);
				}
			}
			, false);
		} else if (document.attachEvent){
			document.attachEvent('onkeydown', function(event){
				if(event.keyCode == Event.KEY_RETURN){
					if (searchBarHandler.clearFields == true) {
	                	searchBarHandler.resetFilters();
	                	searchBarHandler.resetCurrentPage();
	            	}
					searchBarHandler.clickSearch();
				}
			});
		};
    },
    
    /**
     * Sets the value of the username form field in advanced filters, used
     * when the myActivities only values is bookmarked and sent to someone else.
     * We save both values so that the search doesn't loose its integrity.
     * 
     * @param element the dom element in question
     */
    searchUser: function(element) {
    	var userName = this.trim(element.innerHTML);
    	this.resetAll();		
    	$(SearchBarHandlerConstants.USERNAME_ID).setValue(userName);
    	this.showFilters();
    	this.clickSearch();
    },
    
    /**
     * Used througout the page to click the real search button.  Checks if 
     * the value of the location search field is anything besides "Current Search
     * Area" and if so, clears out the bounding box search.  Disables the search
     * button until the page is completely re rendered to stop eager clickers.  
     * (Thats you jason)
     */
    clickSearch: function() {
		this.clickCheck();		
		searchBarHandler.resetCurrentPage();
        searchBarHandler.showSearchProgress();
		$(SearchBarHandlerConstants.REAL_SEARCH_BUTTON).click();    	
		$(SearchBarHandlerConstants.REAL_SEARCH_BUTTON).disabled = true;
    },
    
	/**
	* This function checks to see if we need to clear out the lat/lon to send to our API or simply send a location
	*/
    clickCheck: function() {
		// In the case of someone entering a location, we need to clear out the user map defined bounding box
    	if (($(SearchBarHandlerConstants.LOCATION_ID).value != bundle_activitysearch_api.current_map_search) && ($(SearchBarHandlerConstants.LOCATION_ID).value != "")) {			
 			$(SearchBarHandlerConstants.MAX_LAT_ID).setValue("");
 	    	$(SearchBarHandlerConstants.MAX_LON_ID).setValue("");
 	    	$(SearchBarHandlerConstants.MIN_LAT_ID).setValue("");
 	    	$(SearchBarHandlerConstants.MIN_LON_ID).setValue("");			
    	} 
		else if ($(SearchBarHandlerConstants.USERNAME_ID).value != "") {
			// We can do an user search with either "Current Map View" or the field can simply be blank as well
		}		
		// else we treat it like "Current Map View"
		else {
			$(SearchBarHandlerConstants.LOCATION_ID).setValue(bundle_activitysearch_api.current_map_search);
			$(SearchBarHandlerConstants.CURRENT_MAP_VIEW_ID).setValue(true);
		}
	},
	
    /**
     * Used for toggling between the select my activities only, and search by username option in explore
     * search.  Returns the field to its normal state
     * 
     * @param field the dom element that is the field
     * @param fieldLabel the label identifying the field
     */
    enable: function(field, fieldLabel) {
    	field.removeAttribute(SearchBarHandlerConstants.DISABLED);
    	fieldLabel.removeClassName(SearchBarHandlerConstants.DISABLED);
    },

    /**
     * Used for toggling between the select my activities only, and search by username option in explore
     * search.  Takes the field to a disabled "grayed out" state.
     * 
     * @param field the dom element that is the field
     * @param fieldLabel the label identifying the field
     */
    disable: function(field, fieldLabel) {
    	field.setAttribute(SearchBarHandlerConstants.DISABLED, "true");
        fieldLabel.addClassName(SearchBarHandlerConstants.DISABLED);
    },
    
    /**
     * Hides the result entry passed in and displays the expanded result entry 
     * 
     * @param collapsedEntry {Element}
     */
    showFilters: function() {
        // Switch classnames
        if (this.searchBox.hasClassName(SearchBarHandlerConstants.SEARCH_CLASS)) {
            this.searchBox.removeClassName(SearchBarHandlerConstants.SEARCH_CLASS);
            this.searchBox.addClassName(SearchBarHandlerConstants.ADVANCED_SEARCH_CLASS);
        }
        
        this.showFilterButton.hide();
        this.hideFilterButton.show();
        this.filtersBox.appear({duration: 0.5});
    },
    
    /**
     * Hides the expanded result entry passed in and displays the collapsed result entry
     * 
     * @param expandedEntry {Element} 
     */
    hideFilters: function() {
        
        this.hideFilterButton.hide();
        this.showFilterButton.show();
        this.filtersBox.hide();

        // Switch classnames
        if (this.searchBox.hasClassName(SearchBarHandlerConstants.ADVANCED_SEARCH_CLASS)) {
            this.searchBox.removeClassName(SearchBarHandlerConstants.ADVANCED_SEARCH_CLASS);
            this.searchBox.addClassName(SearchBarHandlerConstants.SEARCH_CLASS);
        }
    },       
    
    /**
     * Reset top part of the search bar
     */
    resetSearch: function() {    	
    	var keyword = $(SearchBarHandlerConstants.KEYWORD_ID);
    	var location = $(SearchBarHandlerConstants.LOCATION_ID);
    	
    	keyword.setValue("");
    	location.setValue("");
    },
    
    /**
     * Reset current page
     */
    resetCurrentPage: function() {
    	var currentPage = $(SearchBarHandlerConstants.CURRENT_PAGE_ID);
    	
    	currentPage.setValue(1);
    },
    
    /**
     * Reset bottom part of the search bar
     */
    resetFilters: function() {
    	var all = $(SearchBarHandlerConstants.USERNAME_ID);
    	var mine = $(SearchBarHandlerConstants.MY_ACTIVITIES_ID);
    	var activity = $(SearchBarHandlerConstants.ACTIVITY_TYPE_SELECT_ID);
    	var event = $(SearchBarHandlerConstants.EVENT_TYPE_SELECT_ID);
    	var time = $(SearchBarHandlerConstants.TIME_SELECT_ID);
    	var distanceMin = $(SearchBarHandlerConstants.MIN_DISTANCE_ID);
    	var distanceMax = $(SearchBarHandlerConstants.MAX_DISTANCE_ID);
    	var timeMin = $(SearchBarHandlerConstants.MIN_TIME_ID);
    	var timeMax = $(SearchBarHandlerConstants.MAX_TIME_ID);
    	var elevationMin = $(SearchBarHandlerConstants.MIN_ELEVATION_ID);
    	var elevationMax = $(SearchBarHandlerConstants.MAX_ELEVATION_ID);
    	var start = $(SearchBarHandlerConstants.START_ID);
    	var end = $(SearchBarHandlerConstants.END_ID);   
    	/*var maxLat = $(SearchBarHandlerConstants.MAX_LAT_ID);
    	var maxLon = $(SearchBarHandlerConstants.MAX_LON_ID);
    	var minLat = $(SearchBarHandlerConstants.MIN_LAT_ID);
    	var minLon = $(SearchBarHandlerConstants.MIN_LON_ID);*/ 	
    	var startNear = $(SearchBarHandlerConstants.LOCATION_ID);
    	
    	// Fields
    	distanceMin.setValue('');
    	distanceMax.setValue('');
    	timeMin.setValue('');
    	timeMax.setValue('');
    	elevationMin.setValue('');
    	elevationMax.setValue('');    	
    	start.setValue('');
    	end.setValue('');
    	/*minLat.setValue('');
    	minLon.setValue('');
    	maxLat.setValue('');
    	maxLon.setValue('');*/
    	// Drop-downs
    	activity.selectedIndex = 0;
    	event.selectedIndex = 0;
    	time.selectedIndex = 0;
    	
    	if (all.value != "" && mine != null) {
    		this.enable(mine, $('myField'));
    	}
    	
		all.setValue('');
		
    	if (mine != null && mine.checked) {
    		mine.checked = false;
    		this.enable(all, $('usernameField'));
    	}
    	
    	if (startNear.value == bundle_activitysearch_api.current_map_search){
    		startNear.setValue('');			
    	}
    	
		$(SearchBarHandlerConstants.CURRENT_MAP_VIEW_ID).setValue(false);
    	$(SearchBarHandlerConstants.CUSTOM_DATES_ID).hide();
    },
    
    /**
     * This will trim any string it is given
     */
    trim: function(str) {
    	var	str = str.replace(/^\s\s*/, ''),
    		ws = /\s/,
    		i = str.length;
    	while (ws.test(str.charAt(--i)));
    	return str.slice(0, i + 1);
    },
    
    /**
     * Reset all of search bar
     */
    resetAll: function() {
    	this.resetSearch();
    	this.resetFilters();
    },
    
    /**
     * Shows search progress
     */
    showSearchProgress: function() {
    	$(SearchBarHandlerConstants.SEARCH_PROGRESS).show();
    },
    
    /**
     * Hides search progress
     */
    hideSearchProgress: function() {
    	$(SearchBarHandlerConstants.SEARCH_PROGRESS).hide();
    }
});