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

var HomeAssistant = Class.create({
	
    initialize: function(params) {
		this.viewSelectorModel = {currentGenre: "popular"};
		this.cmdMenuModel = {items: [{label: $L('Videos'), submenu:'videos-menu'}]};		
		this.historyTotalCount = 0;
    },
    
    setup: function() {
		// setup application menu
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems: true}, AppAssistant.appMenuModel);
		
		// setup bottom menus		
		this.controller.setupWidget('videos-menu', undefined, this.videosMenuModel);				
		this.controller.setupWidget(Mojo.Menu.commandMenu, {menuClass: "no-fade"}, this.cmdMenuModel);
		
		// setup search text field widget
		var attributes = {
      		hintText: $L('Search All Videos...'),
			focus: true,
	  		enterSubmits: true,
			multiline: false,
			modelProperty: 'original',
			modifierState: Mojo.Widget.sentenceCase,
			focusMode: Mojo.Widget.focusInsertMode,
			requiresEnterKey: true,
			changeOnKeyPress: true
    	};
  		this.searchStrModel = {
      		'original' : ""
    	};
    	this.controller.setupWidget('search_string', attributes, this.searchStrModel);
    	$('search_string').observe(Mojo.Event.propertyChange, this.searchQuerySend.bindAsEventListener(this));
		
		// initiate search when tapping on search icon
		$('search_status_icon').observe(Mojo.Event.tap, this.searchQuerySendHelper.bindAsEventListener(this));
	
		// 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() {
		$('search_string').mojo.focus();
		this._checkHistoryCount();
	},
	
	itemsCallback: function(listWidget, offset, count) {		
		Mojo.Log.info("Youtube App: Home: itemsCallback: offset %d, count %d, curView %s", offset, count, this.viewSelectorModel.currentGenre);
		var newCount = count <= this.maxItemsPerQuery ? count : this.maxItemsPerQuery; 
		
		// TODO remove this hack when times are better :)
		if (this.lastQuery 
			&& this.lastQuery.genre == this.viewSelectorModel.currentGenre
			&& this.lastQuery.offset == offset
			&& this.lastQuery.count == newCount
			&& this.viewSelectorModel.currentGenre != "history")
		{
			// 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: Home: itemsCallback: @@@@@@@@@@@@@@@ already sent this query... returning");
			return;
		}
		else {
			// save this query
			this.lastQuery = {
				'genre': this.viewSelectorModel.currentGenre, 
				'offset': offset,
				'count': newCount
			}
		}
		
		
		if (this.viewSelectorModel.currentGenre == "popular") {
			AppAssistant.api.mostPopular(offset+1, newCount, 
				this.videoCallback.bind(this, listWidget, offset, count, newCount, "popular"));
		}
		else if (this.viewSelectorModel.currentGenre == "mostviewed") {
			AppAssistant.api.mostViewed(offset+1, newCount, 
				this.videoCallback.bind(this, listWidget, offset, count, newCount, "mostviewed"));
		}
		else if (this.viewSelectorModel.currentGenre == "history") {
			if (this.historyTotalCount > 0 && offset < this.historyTotalCount) {
				Mojo.Log.info("Youtube App: Home: itemsCallback: history.selectByIndex offset %d, count %d", offset, count);
				AppAssistant.history.selectByIndex(offset, count, 
					this.videoHistoryCallback.bind(this, listWidget, offset, count));
			}
		}
	},
	
	videoHistoryCallback: function(listWidget, offset, count, result){
		// if view type changed while we were getting this result set, don't do anything
		if (this.viewSelectorModel.currentGenre != "history"){
			Mojo.Log.info("Youtube App: Home: videoHistoryCallback: view type changed, just return");
			return;
		}
		
		Mojo.Log.info("Youtube App: Home: videoHistoryCallback: offset %d, count %d, listLen %d", 
			offset, count, listWidget.mojo.getLength());
		if (result) {
			Mojo.Log.info("Youtube App: Home: videoHistoryCallback: 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: Home: videoHistoryCallback: setting total list size to %d", this.historyTotalCount);
			listWidget.mojo.setLength(this.historyTotalCount);
		} 
		else if (result && result.length > 0) {
			listWidget.mojo.noticeUpdatedItems(offset, result);
		}
	},
	
	videoCallback: function(listWidget, offset, originalCount, count, viewType, result, size){		
		// if view type changed while we were getting this result set, don't do anything
		if (viewType != this.viewSelectorModel.currentGenre) {
			Mojo.Log.info("Youtube App: Home: videoCallback: view type changed, just return");
			return;
		}
		
		Mojo.Log.info("Youtube App: Home: videoCallback: offset %d, count %d, listLen %d", 
			offset, count, listWidget.mojo.getLength());
		if (result) {
			Mojo.Log.info("Youtube App: Home: videoCallback: results len %d", result.length);
			//Mojo.Log.info("Youtube App: Home: videoCallback: results len %j", result[0]);
		}
			
		// 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: Home: videoCallback: setting total list size to %d", size);
			listWidget.mojo.setLength(parseInt(size));
		} 
		else if (result && result.length > 0) {
			listWidget.mojo.noticeUpdatedItems(offset, result);
		}
		
		// TODO HACK: 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: Home: 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);
			}	
		}
	},
	
	genreChanged: function() {
		Mojo.Log.info("Youtube App: Home: genreChanged: %s", this.viewSelectorModel.currentGenre);
		
		// show or hide "clear" menu button and update the list widget
		if (this.viewSelectorModel.currentGenre == "history") {
			// show clear menu button
			this.cmdMenuModel.items[1] = {label: $L('Clear'), command: 'clear'};
			this._checkHistoryCount(true); // force list refresh
		}
		else {
			var lw = this.controller.get('videosList');
			lw.mojo.setLength(0);
			this.controller.getSceneScroller().mojo.revealTop(0);
			this.itemsCallback(lw, 0, this.maxItemsPerQuery);
			// hide "clear" menu button
			this.cmdMenuModel.items[1] = {};
		}
		
		// update the check mark position
		for (var i = 0; i < this.videosMenuModel.items.length; i++) {
			if (this.videosMenuModel.items[i].command == this.viewSelectorModel.currentGenre) {
				this.videosMenuModel.items[i].chosen = true;
				$('list_header_text').innerHTML = this.videosMenuModel.items[i].label;
			}
			else {
				this.videosMenuModel.items[i].chosen = false;
			}
		}
		
		this.controller.modelChanged(this.cmdMenuModel, this);
		this.controller.modelChanged(this.videosMenuModel, this);
	},
	
	searchQuerySend: function(event) {
		Mojo.Log.info("Youtube App: Home: searchQuerySend");
		
		if (event.originalEvent != undefined && event.originalEvent.type == "keyup") 
		{
			if (event.originalEvent.keyCode == 13) {
				this.searchQuerySendHelper();	
			}
			else {
				if (event.value && event.value.length > 0) {
					if (!$('search_status_icon').hasClassName('typing')) {
						$('search_status_icon').addClassName('typing')
					}
				}
				else {
					if ($('search_status_icon').hasClassName('typing')) {
						$('search_status_icon').removeClassName('typing')
					}
				}
			}
		}
	},
	
	searchQuerySendHelper: function() {
		// remove begining and trailing spaces
		var searchStr = this.searchStrModel.original;
		searchStr = searchStr.replace(/^\s+|\s+$/g, '');
		Mojo.Log.info("Youtube App: Home: searchQuerySendHelper searchStr *%s*", searchStr);
		
		// reset the value of the search field
		this.searchStrModel.original = "";
		this.controller.modelChanged(this.searchStrModel, this);
		
		if ($('search_status_icon').hasClassName('typing')) {
			$('search_status_icon').removeClassName('typing');
		}
		
		if (searchStr.length > 0) {
			Mojo.Controller.stageController.pushScene("search", searchStr, "search");
		}
		else {
			// focusing field right away has no effect. Seems that 
			// search button gains focus first. So, delay a little.
			setTimeout("$('search_string').mojo.focus()", 200);
		}
	},
	
	handleCommand: function(event) {
		if (event.type == Mojo.Event.command) {
			
			if (this.viewSelectorModel.currentGenre == event.command){
				// if nothing changed just return
				return;
			}
			
			if (event.command == 'clear') {
				// Clear history
				AppAssistant.history.deleteAll(this._checkHistoryCount.bind(this));
				event.stop(event);
			}
			else if (event.command == 'popular' || 
					 event.command == 'mostviewed' ||
					 event.command == 'history') 
			{
				this.viewSelectorModel.currentGenre = event.command;
				this.genreChanged();
				event.stop(event);
			}
			else {
				AppAssistant.common.handleCommand(event);	
			}
		}
	},
	
	// checks if history count has changed and updates the list widget if needed
	_checkHistoryCount: function(forceRefresh) {
		Mojo.Log.info("Youtube: Home _checkHistoryCount");
		// check if history count has changed 
		AppAssistant.history.totalCount(
			function(count) {
				Mojo.Log.info("Youtube: Home _checkHistoryCount: this.historyTotalCount is %d", count);
				this.historyTotalCount = count;
				var lw = this.controller.get('videosList');
				
				// if history count has changed or we have been called
				// because the view has changed: we need to refresh the list
				if (forceRefresh || 
					(this.viewSelectorModel.currentGenre == "history" 
					&& lw.mojo.getLength() != this.historyTotalCount))
				{
					Mojo.Log.info("Youtube: Home _checkHistoryCount: counts don't match! Refreshing the list");
					lw.mojo.setLength(0);
					this.controller.getSceneScroller().mojo.revealTop(0);
					this.itemsCallback(lw, 0, this.maxItemsPerQuery);
				}
			}.bind(this));
	},
						
	videosMenuModel: {label: $L('Videos'), 
					items: [
						{label: $L('Popular'), command: 'popular', chosen: true}, 
						{label: $L('Most Viewed'), command: 'mostviewed', chosen: false},
						{label: $L('History'), command: 'history', chosen: false}
					]},
					
	maxItemsPerQuery: 10,
	
});
