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

/**
* The assistant for the Bookmarks scene.
*/
function BookmarksAssistant(webPreferences) {
	this._webPreferences = webPreferences;
	this.bookmarkStore = new BookmarkStore({database: Mojo.Controller.appController.assistant.getDatabase()});
	this.bookmarksModel = $A();
	this.urlToBookmark = $H();
	this.usingBookmarksDb = false;
}

BookmarksAssistant.Menu = {

	Clear: {
		label: $L('Clear Bookmarks'),
		command: 'clear-bookmarks-command'
	}
};

BookmarksAssistant.prototype.setup = function() {

	try {
		this.controller.setupWidget('bookmarksList',
						{itemTemplate:'bookmarks/bookmarks-entry',
						 listTemplate:'bookmarks/bookmarks-container',
						 itemsCallback:this._retrieveItemsCallback.bind(this),
						 swipeToDelete:true,
						 reorderable:true});
		this.bookmarksListWidget = this.controller.get('bookmarksList');

		this._onListSelectionHandler = this._onListSelection.bindAsEventListener(this);
		this._onListDeleteHandler = this._listDeleteHandler.bindAsEventListener(this);
		this._onListReorderHandler = this._listReorderHandler.bindAsEventListener(this);

		var appMenuModel = {
			visible: true,
			items: [
				MenuData.ApplicationMenu.ShowBookmarks,
				MenuData.ApplicationMenu.ShowHistory,
				BookmarksAssistant.Menu.Clear
			]
		};

		this.controller.setupWidget(Mojo.Menu.appMenu, undefined, appMenuModel);

	}
	catch (e) {
		Mojo.Log.logException(e, 'BookmarksAssistant.setup');
	}
};

BookmarksAssistant.prototype.cleanup = function(event) {
};

BookmarksAssistant.prototype.activate = function() {

	this.bookmarksListWidget.addEventListener(Mojo.Event.listTap, this._onListSelectionHandler);
	this.bookmarksListWidget.addEventListener(Mojo.Event.listDelete, this._onListDeleteHandler);
	this.bookmarksListWidget.addEventListener(Mojo.Event.listReorder, this._onListReorderHandler);

	// Doing this now because the read callback needs the widget to be
	// instantiated and this happens after setup.
	this._resetBookmarkList();
	this._readBookmarks();
};

BookmarksAssistant.prototype.deactivate = function(event) {

	Mojo.Event.stopListening(this.bookmarksListWidget, Mojo.Event.listTap, this._onListSelectionHandler);
	Mojo.Event.stopListening(this.bookmarksListWidget, Mojo.Event.listDelete, this._onListDeleteHandler);
	Mojo.Event.stopListening(this.bookmarksListWidget, Mojo.Event.listReorder, this._onListReorderHandler);
};

/** @private */
BookmarksAssistant.prototype._resetBookmarkList = function() {
	delete this.bookmarksModel;
	this.bookmarksModel = $A();
	this.urlToBookmark = $H();
	var lir = this.bookmarksListWidget.mojo.getLoadedItemRange();
	this.bookmarksListWidget.mojo.noticeRemovedItems(lir.offset, lir.limit);
};

/**
 * Start reading bookmarks (actual read is asynchronous).
 * @private
 */
BookmarksAssistant.prototype._readBookmarks = function() {

	if (!this.usingBookmarksDb) {
		this.usingBookmarksDb = true;
		this.bookmarkStore.readBookmarks(
			new BookmarkFolder(),
			null,
			this._onBookmarksReadSuccess.bind(this),
			this._onBookmarksReadFailure.bind(this) );
	}
};

BookmarksAssistant.prototype._deleteImage = function(fname) {
	
	this.controller.serviceRequest('palm://com.palm.browserServer/deleteImage', {
			parameters: {file: fname},
			onFailure: function() {
				Mojo.Log.error("Failure deleting file: %s", fname);
			}
		});
};

BookmarksAssistant.prototype._deleteBookmarkImages = function(urlRef) {
	this._deleteImage(urlRef.iconFile32);
	this._deleteImage(urlRef.iconFile64);
	this._deleteImage(urlRef.thumbnailFile);
};

BookmarksAssistant.prototype._clearBookmarks = function() {

	var self = this;
	this.controller.showAlertDialog({
		onChoose: function(value) {
			if (value === 'ok') {
				self.bookmarkStore.deleteBookmark('ALL', 
					function() {
						// Now delete all of the bookmark images.
						for (var idx=0, len = self.bookmarksModel.length; idx < len; idx++) {
							self._deleteBookmarkImages(self.bookmarksModel[idx]);
						}
						self._resetBookmarkList();						
					},
					
					function(sqlFunc, params) {
						Mojo.Log.error("Unable to delete all bookmarks");
					});
			}
		},
		title:$L('Clear Bookmarks'),
		message:$L('Are you sure you want to clear all bookmarks?'),
		cancelable:true,
		choices:[
			{label:$L('Clear Bookmarks'), value:'ok', type:'negative'},
			{label:$L('Cancel'), value:'cancel'}
		]
	});
};

/**
 * Called by the BookmarksStore when it has finished successfully reading the
 * bookmarks from the database
 *
 * @param {BookmarkFolder} bookmarkFolder
 * @private
 */
BookmarksAssistant.prototype._onBookmarksReadSuccess = function(bookmarkFolder) {

	try {
		for (var d = 0; d < bookmarkFolder.contents.length; d++) {
			var item = bookmarkFolder.contents[d];
			if (item instanceof UrlReference) {

				this.urlToBookmark.set(item.url, item);
				item.dispUrl = UrlUtil.cleanup(item.url);
				if (item.title.empty()) {
					item.title = item.dispUrl;
					item.dispUrl = '&nbsp;';
				}
				else {
					item.title = item.title.escapeHTML();
				}

				this.bookmarksModel.push(item);
			}
		}

		this.bookmarksListWidget.mojo.setLength(this.bookmarksModel.length);
	}
	finally {
		this.usingBookmarksDb = false;
	}
};

/** @private */
BookmarksAssistant.prototype._onBookmarkUpdateSuccess = function() {
};

/** @private */
BookmarksAssistant.prototype._onBookmarkUpdateFailure = function(sqlFunc, params) {
	Mojo.Log.error("ERROR updating bookmark, code: %d, message: '%s'.", params.code, params.message);
};

/**
 * Called by the BookmarksStore when it has failed reading thie bookmarks
 * from the database.
 *
 * @param {Object} msg
 * @param {Object} e
 * @private
 */
BookmarksAssistant.prototype._onBookmarksReadFailure = function(msg, e) {
	Mojo.Log.error("Error reading bookmarks: %s", e.toString());
	this.usingBookmarksDb = false;
};

/**
 * This callback is called by the URL search list to retrieve model objects to be
 * displayed in the list.
 *
 * @param {Object} listWidget	The widget to add the items to.
 * @param {Number} offset	The zero based item offset
 * @param {Number} count	The number of items to retrieve.
 *
 * @private
 */
BookmarksAssistant.prototype._retrieveItemsCallback = function(listWidget, offset, count) {

	// The bookmarks model has already been fully loaded but we only lazily load
	// the list.
	var model = this.bookmarksModel.slice(offset, offset+count);
	listWidget.mojo.noticeUpdatedItems(offset, model);
};

BookmarksAssistant.prototype._listReorderHandler = function(event) {
	this.bookmarksModel.splice(this.bookmarksModel.indexOf(event.item), 1);
	this.bookmarksModel.splice(event.toIndex, 0, event.item);
	for(var i=0; i<this.bookmarksModel.length;i++)	{
		this.bookmarksModel[i].index=i;
		this.bookmarkStore.insertOrUpdateBookmark( this.bookmarksModel[i],
			this._onBookmarkUpdateSuccess.bind(this),
			this._onBookmarkUpdateFailure.bind(this) );

	}
};

BookmarksAssistant.prototype._listDeleteHandler = function(event) {
	var urlRef = event.item;
	this.bookmarksModel.splice(this.bookmarksModel.indexOf(urlRef), 1);
	this.bookmarkStore.deleteBookmark(event.item.id,
		this._onBookmarkDeleteSuccess.bind(this, urlRef),
		this._onBookmarkDeleteFailure.bind(this) );

};

/** @private */
BookmarksAssistant.prototype._onBookmarkDeleteSuccess = function(urlRef) {
	this._deleteBookmarkImages(urlRef);
};

/** @private */
BookmarksAssistant.prototype._onBookmarkDeleteFailure = function(sqlFunc, params) {
	Mojo.Log.error("ERROR deleting bookmark, code: %d, message: '%s'.", params.code, params.message);
};

BookmarksAssistant.prototype._onListSelection = function(event) {

	var targetRow = this.controller.get(event.originalEvent.target);
	var selectedInfo = targetRow.match('#info');

	var urlRef = event.item;
	var onClose = function(saved) {
		if (saved) {
			this._resetBookmarkList();
			this._readBookmarks();
		}
	}.bind(this);

	if (selectedInfo) {
		var params = {task: BookmarkDialogAssistant.editBookmarkTask,
			urlReference: urlRef,
			sceneController: this.controller,
			bookmarkStore: this.bookmarkStore,
			onClose: onClose,
			deleteImage: this._deleteImage.bind(this)};

		BookmarkDialogAssistant.showDialog(params);
	}
	else {
		this.controller.stageController.popScene({type: 'bookmarks', payload: urlRef});
	}
};

BookmarksAssistant.prototype.handleCommand = function(event) {

	try {
		switch (event.type) {

			case Mojo.Event.back:
				if (this.controller.stageController._sceneStack.size() > 1) {
					Event.stop(event);
					this.controller.stageController.popScene();
				}
				break;

			case Mojo.Event.command:

				switch (event.command) {

					case MenuData.ApplicationMenu.ShowHistory.command:
						this._openHistoryView();
						break;

					case BookmarksAssistant.Menu.Clear.command:
						this._clearBookmarks();
						break;

					case Mojo.Menu.prefsCmd:
						this.prefsSceneActive = true;
						this._openPreferencesView();
						break;

					case Mojo.Menu.helpCmd:
						this._showHelpCommand();
						break;
				}
				break;

			case Mojo.Event.commandEnable:

				// Standard Application Menu commands.
				if (event.command === Mojo.Menu.prefsCmd ||
				    event.command === Mojo.Menu.helpCmd) {

					event.stopPropagation(); // Enable the chosen menuitems
					return;
				}

				if (event.command === MenuData.ApplicationMenu.ShowBookmarks.command) {
					event.preventDefault();
					return;
				}

				break;
		}
	}
	catch (e) {
		Mojo.Log.logException(e, 'BookmarksAssistant#handleCommand');
	}
};

BookmarksAssistant.prototype._openPreferencesView = function() {

	this.controller.stageController.pushScene('preferences', this._webPreferences);

};

BookmarksAssistant.prototype._openHistoryView = function() {

	this.controller.stageController.swapScene(
		{
			name: 'history',
			transition: Mojo.Transition.crossFade
		},
		this._webPreferences);
};

BookmarksAssistant.prototype._showHelpCommand = function() {

	// Launch help
	AppAssistant.launchHelp();
};



