/**
* @fileoverview This file contains the static object Search. 
* @author Sara Lin
* @version 0.1
*/

/**
* The search object for general search functionalities
* @namespace
*/
var Search = {
	tab: null,
	activePage: null,
	floorJump: null,
	idJump: null,
	
	/**
	* initializes the keyword and category searches
	*/
	initialize: function() {
		this.tab = Main.tabs.getTab('search');
		
		this.floorJump;
		this.idJump;
		
		this.jumpToItem = this._jumpToItem.bindAsEventListener(this);
		this.jumpToFloor = this._jumpToFloor.bindAsEventListener(this);

		Search.keyword.initialize();
		Search.category.initialize();
	},
	
	/**
	* invoke floor switch to the floor level and select the item on that floor
	* @param {number} floor level of the floor to jump to
	* @param {number} item id of the selected item
	*/
	jumpToResult: function(floor, id) {
		this.floorJump = floor;
		this.idJump = id;
		FloorManager.switchFloor(floor, Search.showItemTab);
	},
	
	/**
	* @event get the floor to be jumped to from the invoked event element and switch to that floor
	*/
	_jumpToFloor: function(event) {
		var item = Event.element(event);
		Search.floorJump = item.className.split('_')[1];
		FloorManager.switchFloor(Search.floorJump);
	},
	
	/**
	* @event get the item id and floor level from the event element, jump to the selected item on the floor
	*/
	_jumpToItem: function(event) {
		var item = Event.element(event);
		Search.idJump = item.id.split('_')[1];
		Search.floorJump = item.id.split('_')[2];
		FloorManager.switchFloor(Search.floorJump,Search.showItemTab);
	},
	
	/**
	* select the item on current floor
	*/
	showItemTab: function() {
		FloorManager.floors[Search.floorJump].items[Search.idJump]._center();
		FloorManager.floors[Search.floorJump].items[Search.idJump].click();
	},
	
	/**
	* initialize search tab and observe search events
	*/
	initializeTab: function(searchFun) {
		var url = base_url+'search/getSearchTab';
		//get search tab
		new Ajax.Request(url, {
			onSuccess: function(response) {
				Search.tab.tabElem.innerHTML = response.responseText;	
				
				//observe page link events
				Search.observePageLinks();
			}
		});
	},
	
	/**
	* observe page links for keyword and category pages. not used/implemented currently.
	*/
	observePageLinks: function() {
		if ($('keywordSearchLink'))
			Event.observe('keywordSearchLink', 'click', Search.keyword.showPage);
		if ($('categorySearchLink'))
			Event.observe('categorySearchLink', 'click', Search.category.showPage);
	},
	
	/**
	* switch active page to selectedPage, not implemented.
	* @param {object} selectedPage the page selected to view.
	*/
	switchPage: function(selectedPage) {
		if (Search.activePage != null) {
			Search.activePage.body.hide();
			Search.activePage.link.className = '';
		}
		$(selectedPage.body).show();
		selectedPage.link.className = 'active';
		Search.activePage = selectedPage;
	}
}

/**
* keyword search page
* @namespace
*/
Search.keyword = {
	link: null,
	body: null,
	keyword: null,
	pageNum: 1,
	
	/**
	* initialize autocompleter, setup searchbox
	*/
	initialize: function() {
		var url = base_url+"search/ajaxsearch/";
		new Ajax.Autocompleter("searchautocomplete", "autocomplete_choices", url, {});
		
		DefaultInput.setDefaultInput("keyword or call number", $('searchautocomplete'));
		this.searchKeyword = this._searchKeyword.bindAsEventListener(this);
		this.searchKeywordPage = this._searchKeywordPage.bindAsEventListener(this);
		
		Event.observe('searchbox', "submit", this.searchKeyword);
	},
	
	/**
	* keyword search wrapper for a fresh search
	*/
	_searchKeyword: function() {
		var keyword = $('searchautocomplete').value;
		this.keyword = keyword;
		this._search(keyword, 1);
	},
	
	/**
	* searches the keyword and return either a item tab for the found item or a list of items in the search page
	* @param {String} keyword
	*/
	_search: function(keyword) {
		if (keyword=="") {
			return 0;
		}
		
		if (this.keyword!=keyword)
			this.keyword = keyword;
		
		var url = base_url+"search/searchKeyword";
		var queryArray = new Array(keyword);
		var pageNum = 1;
		var searchJSON;
		url = encodeURL(url, queryArray);
		
		new Ajax.Request(url, {
			onSuccess: function(response) {
				searchJSON = response.responseText.evalJSON();
				if (searchJSON.found) {
					Search.idJump = searchJSON.result.split('_')[1];
					Search.floorJump = searchJSON.result.split('_')[2];
					FloorManager.switchFloor(Search.floorJump,Search.showItemTab);
				}
				else {
					Main.trackPage('/search/'+keyword+'.html');
					Search.keyword._getSearchResults(keyword, pageNum);
				}
			}
		});
	},
	
	/**
	* show the search result in the search tab.  Attach event handlers for pagination and for redirecting to the selected item's item tab.
	* @param {String} keyword
	* @param {number} pageNum page number of the current result page
	*/
	_getSearchResults: function(keyword, pageNum) {
		var tab = Main.tabs.showTab('search');
		
		var url = base_url+"search/getSearchResults";
		var queryArray = new Array(keyword, pageNum);
		url = encodeURL(url, queryArray);
		
		new Ajax.Request(url, {
			onSuccess: function(response) {
				Search.tab.tabElem.innerHTML = response.responseText;
				
				//attach events to search results
				var items = $$('#keywordSearchResultPage .cat_item a');
				items.each(function(item) {
					Event.observe(item, "click",Search.jumpToItem);
				});
				var floors = $$('#keywordSearchResultPage .cat_floor a');
				floors.each(function(floor) {
					Event.observe(floor, "click",Search.jumpToFloor);
				});
				
				//attach events to pagination
				var pagination = $$('#keywordSearchResultPage .pagination a');
				pagination.each(function(pageLink) {
					pageLink = $(pageLink);
					if (!pageLink.hasClassName('selected')) {
						Event.observe(pageLink,"click",Search.keyword.searchKeywordPage);
					}
				});
			}
		});
	},
	
	/**
	* @event get the results for a given keyword at a selected page
	*/
	_searchKeywordPage: function(event) {
		var element = Event.element(event);
		if (!element.hasClassName('selected')) {
			var id = element.className.split('_');
			if (id[0]=='pageID') {
				Search.keyword.pageNum = id[1];
				Search.keyword._getSearchResults(this.keyword, this.pageNum);
			}
		}
	}
}

/**
* category page object
* @namespace
*/
Search.category = {
	link: null,
	body: null,
	title: null,
	pageNum: 1,
	
	/**
	* setup the object and event listeners
	*/
	initialize: function() {
		this.displayCategories = this._displayCategories.bindAsEventListener(this);
		this.searchCategory = this._searchCategory.bindAsEventListener(this);
		this.searchCategoryPage = this._searchCategoryPage.bindAsEventListener(this);
		Event.observe('dirSearch', "click", this.displayCategories);
	},
	
	/**
	* @event invoked when user clicks on the "find by category" link.  shows a list of all library item categories
	*/
	_displayCategories: function(event) {
		var url = base_url+'search/displayCategories';
		
		new Ajax.Request(url, {
			onSuccess: function (response)	{
				Search.tab.tabElem.innerHTML = response.responseText;
				if ($('cat-table')) {
					var catList = $$('#cat-table td a');
					catList.each(function(cat) {
						Event.observe($(cat), "click", Search.category.searchCategory);
					});
				}
			}
		});
		Search.tab.mySystem.changeTab(Search.tab,false);
	},
	
	/**
	@event shows all items in a given category in paginated format
	*/
	_searchCategory: function(event) {
		var element = Event.element(event);
		
		this.title = element.title;
		this.pageNum = 1;
		this._search(this.title, this.pageNum);
		Search.tab.mySystem.changeTab(Search.tab,false);
	},
	
	/**
	* @event shows a list of items within a given category in the selecte page
	*/
	_searchCategoryPage: function(event) {
		var element = Event.element(event);
		if (!element.hasClassName('selected')) {
			var id = element.className.split('_');
			if (id[0]=='pageID') {
				Search.category.pageNum = id[1];
				this._search(this.title, this.pageNum);
			}
		}
	},
	
	/**
	* search for all items within a selected category
	*/
	_search: function(title, pageNum) {
		var url = base_url+'search/searchCategory';
		var queryArray = new Array(title,pageNum);
		url = encodeURL(url, queryArray);
		
		new Ajax.Request(url, {
			onSuccess: function(response) {
				Search.tab.tabElem.innerHTML = response.responseText;
				//attach events to "Find by Category" and "(back)"
				var backLinks = $$('#catSearchResultPage .cat_table_link');
				backLinks.each(function(link) {
					Event.observe(link,"click",Search.category.displayCategories);
				});
				
				//attach events to search results
				var items = $$('#catSearchResultPage .cat_item a');
				items.each(function(item) {
					Event.observe(item, "click",Search.jumpToItem);
				});
				var floors = $$('#catSearchResultPage .cat_floor a');
				floors.each(function(floor) {
					Event.observe(floor, "click",Search.jumpToFloor);
				});
				
				//attach events to pagination
				var pagination = $$('#catSearchResultPage .pagination a');
				pagination.each(function(pageLink) {
					pageLink = $(pageLink);
					if (!pageLink.hasClassName('selected')) {
						Event.observe(pageLink,"click",Search.category.searchCategoryPage);
					}
				});
			}
		});
	}
}