/* Copyright 2009 Palm, Inc.  All rights reserved. */

var SearchAssistant = Class.create({
	
    initialize: function(query, type, swapForHomeScene) {
		this.searchFieldModel = {
			'original': ""
		};
		
		if (type == "search") {
			this.searchFieldModel.original = query;
		}
		
		this.query = query;
		this.viewType = type;
		this.swapHomeSceneOnBack = swapForHomeScene;
    },
    
    setup: function() {
		// setup application menu
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems: true}, AppAssistant.appMenuModel);
		
		// setup search field
		this.searchFieldModel.attributes = {
			hintText: $L('Search All Videos...'),
			focus: true,
			enterSubmits: true,
			multiline: false,
			modelProperty: 'original',
			modifierState: Mojo.Widget.sentenceCase,
			focusMode: Mojo.Widget.focusSelectMode,
			requiresEnterKey: true,
			changeOnKeyPress: true
		};
		this.controller.setupWidget('search_field', this.searchFieldModel.attributes, this.searchFieldModel);
		$('search_field').observe(Mojo.Event.propertyChange, this.searchStrChanged.bindAsEventListener(this));
					
		// initiate search when tapping on search icon
		$('search_status_icon').observe(Mojo.Event.tap, this.searchQueryChangedHelper.bindAsEventListener(this));
		
		// setup list header
		if (this.viewType == "search") {
			$('title_bar_text').innerHTML = $L('Search Results');
		}
		else if (this.viewType == "author") {
			$('title_bar_text').innerHTML = $L('More from: ') + this.query;
			$('total_results_container').style.display = "none";
		}
		else if (this.viewType == "related") {
			$('title_bar_text').innerHTML = $L('Related Videos');
			$('total_results_container').style.display = "none";
		}
	
		// setup videos list
		var attributes =
    	{
			itemTemplate: 'home/list-entry',
			initialAverageRowHeight: 50,
      		itemsCallback: this.itemsCallback.bind(this),
			//optimizedOptIn: true,
			lookahead: 10,
    	};
		this.controller.setupWidget('videosList', attributes, null);
		$('videosList').observe(Mojo.Event.listTap, function(event){ 
				AppAssistant.common.videoSelected(event); 
			});		
    },
	
	activate: function() {
		// in case of cross app launch we want to focus the app only after 
		// search scene is ready to go. This is so that user won't see a
		// home scene flash before we push the search scene
		// "Home scene flash" happens only if app was already running when 
		// it received the cross app launch request.
		Mojo.Log.info("Youtube: search activate: activate stage controller");
		this.controller.stageController.activate();
		$('search_field').mojo.focus();
	},
	
	itemsCallback: function(listWidget, offset, count) {
		Mojo.Log.info("Youtube App: Search: itemsCallback: offset %d, count %d", offset, count);
		var newCount = count <= this.maxItemsPerQuery ? count : this.maxItemsPerQuery; 
		
		// TODO remove this hack when times are better :)
		if (this.lastQuery
			&& this.lastQuery.offset == offset
			&& this.lastQuery.count == newCount)
		{
			// HACK: by-product of the hack in videoCallback.
			// it happens that I call myself to request the next batch say 
			// items 10-20, but list widget does it to. This generates two 
			// requests for the same set of items.
			Mojo.Log.info("Youtube App: Search: itemsCallback: @@@@@@@@@@@@@@@ already sent this query... returning");
			return;
		}
		else {
			// save this query
			this.lastQuery = {
				'offset': offset,
				'count': newCount
			}
		}
		
		if (this.viewType == "author") {
			AppAssistant.api.searchByAuthor(this.query, offset+1, newCount, 
				this.videoCallback.bind(this, listWidget, offset, count, newCount));
		}
		else if (this.viewType == "related") {
			AppAssistant.api.related(this.query, offset+1, newCount, 
				this.videoCallback.bind(this, listWidget, offset, count, newCount));
		} 
		else if (this.viewType == "search" && this.searchFieldModel 
				&& this.searchFieldModel.original) 
		{
			AppAssistant.api.search(this.searchFieldModel.original, offset+1, newCount, 
				this.videoCallback.bind(this, listWidget, offset, count, newCount));
		}	
	},
	
	videoCallback: function(listWidget, offset, originalCount, count, result, size){
		Mojo.Log.info("Youtube App: Search: videoCallback: offset %d, count %d, listLen %d", 
			offset, count, listWidget.mojo.getLength());
	
		if (result) {
			Mojo.Log.info("Youtube App: Search: videoCallback: results len %d", result.length);
		}
			
		// we assume that if the list size is 0, and we have >0 items, that we haven't set the length yet.
		if (listWidget.mojo.getLength() === 0 && result && result.length > 0) {
			listWidget.mojo.noticeAddedItems(0, result);
			Mojo.Log.info("Youtube App: Search: videoCallback: setting total list size to %d", size);
			listWidget.mojo.setLength(parseInt(size));
			
			if (this.viewType == "search") {
				$('total_search_results').innerHTML = size;
			}
		} 
		else if (result && result.length > 0) {
			listWidget.mojo.noticeUpdatedItems(offset, result);
		}
		
		// TODO works for now, but figure out a better way to do this with Jesse
		if (result.length > 0 && originalCount > result.length) {
			// request more items in batches of this.maxItemsPerQuery
			if (result.length + this.maxItemsPerQuery < originalCount) {
				Mojo.Log.info("Youtube App: Search: videoCallback: request more items in batches of this.maxItemsPerQuery, offset %d, count %d", 
					offset+this.maxItemsPerQuery, originalCount-this.maxItemsPerQuery);
				this.itemsCallback(listWidget, offset + this.maxItemsPerQuery, originalCount - this.maxItemsPerQuery);		
			}
			else {
				this.itemsCallback(listWidget, offset+result.length, originalCount-result.length);
			}	
		}
	},
	
	searchStrChanged: function(event) {
		if (event.originalEvent != undefined && event.originalEvent.type == "keyup") 
		{
			if (event.originalEvent.keyCode == 13) {
				this.searchQueryChangedHelper();
			}
			else if (!$('search_status_icon').hasClassName('typing')) {
				$('search_status_icon').addClassName('typing')
			}
		}
	},
	
	searchQueryChangedHelper: function() {
		// remove begining and trailing spaces
		var searchStr = this.searchFieldModel.original;
		searchStr = searchStr.replace(/^\s+|\s+$/g, '');
		Mojo.Log.info("Youtube App: search: searchQueryChangedHelper searchStr *%s*", searchStr);
		
		if (searchStr.length > 0) {
			// if this is a search scene show new search results in place.
			// if it's more from author, or related videos scene type
			// then push another search scene on top
			if (this.viewType == "search") {
				var lw = this.controller.get('videosList');
				lw.mojo.setLength(0);
				this.controller.getSceneScroller().mojo.revealTop(0);
				this.itemsCallback(lw, 0, this.maxItemsPerQuery);
				
				if ($('search_status_icon').hasClassName('typing')) {
					$('search_status_icon').removeClassName('typing')
				}
				$('total_search_results').innerHTML = 0;
				setTimeout("$('search_field').mojo.focus()", 200);
			}
			else {
				this.searchFieldModel.original = "";
				this.controller.modelChanged(this.searchFieldModel, this);
				Mojo.Controller.stageController.pushScene("search", searchStr, "search");
			}
		}
		else {
			// TODO fix it, it should store old string and then restore that one
			// instead of reseting to ""
			this.searchFieldModel.original = "";
			this.controller.modelChanged(this.searchFieldModel, this);
			// focusing field right away has no effect. Seems that 
			// search button gains focus first. So, delay a little.
			setTimeout("$('search_field').mojo.focus()", 200);
		}
	},
	
	handleCommand: function(event) {
		if (event.type == Mojo.Event.back && this.swapHomeSceneOnBack == true) {
			Mojo.Log.info("Youtube: search cleanup: swap scene for scene HOME");
			event.stop();
			this.controller.stageController.swapScene("home");
		}
		else {
			AppAssistant.common.handleCommand(event);
		}
	},
	
	maxItemsPerQuery: 10,
	
});
