var DefaultappsAssistant = Class.create({
	
	initialize: function() {
		this.selectedMimeType = null;
		this.setupCompleteCallback = null;
		this.gotIntialQuery = false;
	},
	
	setup: function() {
		
		this.controller.setupWidget('phoneNumbers', {label: $L("Phone Numbers"), choices: this.phoneNumberChoices,multiline: true}, this.phoneNumberModel);
		this.controller.setupWidget('addresses', {label: $L("Addresses"),choices: this.addressChoices, multiline: true}, this.addressesModel);
		this.controller.setupWidget('emailaddr', {label: $L("Email Addresses"), choices: this.emailAddrChoices, multiline: true}, this.emailAddrModel);
		this.controller.setupWidget('weblinks', {label: $L("Web Links"), choices: this.weblinksChoices, multiline: true}, this.weblinksModel);
		
		Mojo.Event.listen(this.controller.get('phoneNumbers'), Mojo.Event.propertyChange, this.handlePropertyChange.bindAsEventListener(this,'phoneNumbers'));
		Mojo.Event.listen(this.controller.get('addresses'), Mojo.Event.propertyChange, this.handlePropertyChange.bindAsEventListener(this,'addresses'));
		Mojo.Event.listen(this.controller.get('emailaddr'), Mojo.Event.propertyChange, this.handlePropertyChange.bindAsEventListener(this,'emailaddr'));
		Mojo.Event.listen(this.controller.get('weblinks'), Mojo.Event.propertyChange, this.handlePropertyChange.bindAsEventListener(this,'weblinks'));
		
		//Setup for Mime Types List
		this.MimeTypeModel = {
            items: this.fileExtensions,
			'listTitle':$L('File Types')
        };
        
        this.controller.setupWidget('mimeTypeList', {
            itemTemplate: 'defaultapps/list-item',
			listTemplate: 'defaultapps/list-container'
        }, this.MimeTypeModel);
		
		Mojo.Event.listen(this.controller.get('mimeTypeList'), Mojo.Event.listTap, this.handleListTap.bindAsEventListener(this));
		this.mimeTypeListWidget = this.controller.get('mimeTypeList');
		
		var appMenuModel = {
	        visible: true,
	        items: [Mojo.Menu.editItem,Mojo.Menu.helpItem]
	        };
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems:true}, appMenuModel);
		
		this.getDataTypeValues();
		this.getExtenstionMap();
	},
	
	//Delay the Activate until the first service call completes.
	aboutToActivate: function(callback) {
		if(this.gotInitialQuery)
			callback();
		else 
			this.setupCompleteCallback = callback;
	},
	
	//Query the service again to get the modified active handlers for the mime.
	activate: function() {
		if(this.selectedMimeType) {
			this.controller.serviceRequest('palm://com.palm.applicationManager', {
				method: 'listAllHandlersForMime', 
				onSuccess: function(response) {
					if(!response.returnValue)	
						return;
					this.updateMimeTypeList(response.resourceHandlers);
				}.bind(this),
				parameters: {"mime": this.selectedMimeType.mime}
	    	});
		}
	},
	
	cleanup: function() {
		this.fileExtensions.clear();
		this.phoneNumberChoices.clear();
		this.addressChoices.clear();
		this.emailAddrChoices.clear();
		this.weblinksChoices.clear();
	},
	
	//Get the Handlers for all Data Types.
	getDataTypeValues: function() {
		this.cleanupList();
		this.controller.serviceRequest('palm://com.palm.applicationManager', {
			method: 'listAllHandlersForMultipleUrlPattern', 
			onSuccess: this.handleUrlPatternResponse.bind(this),
			onFailure: this.handleUrlPatternResponse.bind(this),
			parameters: {"urls": this.urlPatterns}
	    });
	},
	
	handleUrlPatternResponse: function(response) {
		
		if (!response.returnValue) {
			this.showErrorDialog($L("Unable to get default applications!"));
			return;
		}
		
		//Parse the object
		for(var i=0; i<this.urlPatterns.length; i++) {
			var handlers = response[this.urlPatterns[i]];
			var activeHandler = handlers.activeHandler;
			var alternates = handlers.alternates;
			var choices;
			var model;
			
			switch(i) {
				case 0 	: 	choices = this.phoneNumberChoices;
							model = this.phoneNumberModel;
							this.phoneNumberModel.value = activeHandler.index;
						  	break;
				case 1	: 	choices = this.addressChoices;
							model = this.addressesModel;
							this.addressesModel.value = activeHandler.index;
						  	break;
				case 2	: 	choices = this.emailAddrChoices;
							model = this.emailAddrModel;
							this.emailAddrModel.value = activeHandler.index;
						   	break;
				case 3 	: 	choices = this.weblinksChoices;
							model = this.weblinksModel;
							this.weblinksModel.value = activeHandler.index;
							break;
			}	
			choices.push({"label":activeHandler.appName, "value":activeHandler.index});
			
			if(alternates) {
				model.disabled = false;
				for(var j = 0; j<alternates.length; j++) {
					choices.push({"label":alternates[j].appName, "value":alternates[j].index})
				}
			}	
		}
		
		this.controller.modelChanged(this.phoneNumberModel,this);
		this.controller.modelChanged(this.addressesModel,this);
		this.controller.modelChanged(this.emailAddrModel,this);
		this.controller.modelChanged(this.weblinksModel,this);
		
		//Initial Query is done. UI can draw now.
		this.gotIntialQuery = true;
		if(this.setupCompleteCallback) {
			this.setupCompleteCallback();
			this.setupCompleteCallback = null;
		}		
	},
	
	//Property Change Handler function for List Selectors. It passes the target to identify which list selector value changed.
	handlePropertyChange:function(event,target) {
		if(!event.value)
			return;
		
		var url;
		var index = event.value;
		switch(target) {
			case 'phoneNumbers': url = this.urlPatterns[0];
									break;
			case 'addresses':	url = this.urlPatterns[1];
									break;
			case 'emailaddr':	url = this.urlPatterns[2];
									break;
			case 'weblinks':	url = this.urlPatterns[3];
									break;
		}
		
		this.controller.serviceRequest('palm://com.palm.applicationManager', {
			method: 'swapRedirectHandler', 
			onSuccess: this.handleSwapRedirectResponse.bind(this),
			onFailure: this.handleSwapRedirectResponse.bind(this),
			parameters: {"url": url, "index":index}
	    });
			
	},
	
	handleSwapRedirectResponse: function(response) {
		if(response.returnValue)
			return;
		this.showErrorDialog($L("Unable to change the default application!"));
	},
	
	cleanupList: function() {
		this.phoneNumberChoices.clear();
		this.addressChoices.clear();
		this.emailAddrChoices.clear();
		this.weblinksChoices.clear();
		
		this.controller.modelChanged(this.phoneNumberModel,this);
		this.controller.modelChanged(this.addressesModel,this);
		this.controller.modelChanged(this.emailAddrModel,this);
		this.controller.modelChanged(this.weblinksModel,this);
	},
	
	//Get the list of Extensions and corresponding mime types. 	
	getExtenstionMap: function() {
		this.controller.serviceRequest('palm://com.palm.applicationManager', {
			method: 'listExtensionMap', 
			onSuccess: this.handleExtensionMapResponse.bind(this),
			onFailure: this.handleExtensionMapResponse.bind(this),
	    });
	},
	
	//Parse the Extension list service response. Eliminates the duplicate mime types. Save the list in a hash.
	handleExtensionMapResponse: function(response) {
		if(!response.returnValue || !response.extensionMap)
			return;
		var extList = response.extensionMap;
		var listItem;
		
		for(var i = 0; i<extList.length; i++) {
			listItem = extList[i];
			this.mimeTypes.push(Object.values(listItem).toString());
			this.fileTypes.set(Object.keys(listItem).toString(),Object.values(listItem).toString());
		}
		this.mimeTypes = this.mimeTypes.uniq();
		this.getMimeTypeValues();
	},
	
	getMimeTypeValues: function() {
		this.controller.serviceRequest('palm://com.palm.applicationManager', {
			method: 'listAllHandlersForMultipleMime', 
			onSuccess: this.handleMimeListResponse.bind(this),
			onFailure: this.handleMimeListResponse.bind(this),
			parameters: {"mimes": this.mimeTypes}
	    });
	},
	
	handleMimeListResponse: function(response) {
	
		if (!response.returnValue) {
			this.showErrorDialog($L("Unable to get default applications!"));
			return;
		}
		
		this.MimeTypeModel.items.clear();
		this.controller.modelChanged(this.MimeTypeModel, this);
		
		var keys = this.fileTypes.keys();
		
		for(var i = 0; i< keys.length; i++) {
			
			var resHandler = response[this.fileTypes.get(keys[i])];
			
			if(!resHandler)
				continue;
			
			var activeHandler = resHandler.activeHandler;
			var obj = {};
			
			obj.appName = this.palmAppNames.get(activeHandler.appId) || activeHandler.appName;
			obj.fileExt = keys[i];
			
			if(!obj.appName)
				continue;
						
			if(resHandler.alternates)
				obj.alternates = resHandler.alternates;
			else 
				obj.disabled = 'disabled';
				
			obj.activeHandler = activeHandler;
				
			this.fileExtensions.push(obj);
		}
		this.fileExtensions.sort(this.compareExtension.bind(this));
		this.controller.modelChanged(this.MimeTypeModel, this);
	},
	
	//Comapare function. List will be sorted by extension values.
	compareExtension: function(a,b) {
		var nameA = a.fileExt.toLowerCase();
		var nameB = b.fileExt.toLowerCase();
		if (nameA < nameB) {return -1}
		if (nameA > nameB) {return 1}
		return 0;
	},
	
	handleListTap: function(event) {
		
		if(!event.item)
			return;
			
		var item = event.item;
		
		if(item.disabled && item.disabled === 'disabled')
			return;
			
		this.selectedMimeType = {rowIndex:event.index, mime:item.activeHandler.mime};
		this.controller.stageController.pushScene('mimetype',item);
	},
	
	updateMimeTypeList: function(resHandler) {
		
		if(!resHandler)
			return;
			
		var activeHandler = resHandler.activeHandler;
		var obj;
		//Iterate thru the array and update all rows in list that have the same mime type.
		for(var i = 0; i< this.fileExtensions.length; i++) {
			
			if(this.fileExtensions[i].activeHandler.mime != activeHandler.mime)
				continue;
			obj = {};
			obj = this.fileExtensions[i];
			obj.appName = this.palmAppNames.get(activeHandler.appId) || activeHandler.appName;
		
			if(resHandler.alternates)
				obj.alternates = resHandler.alternates;
			else 
				obj.disabled = 'disabled';
			
			obj.activeHandler = activeHandler;
			this.mimeTypeListWidget.mojo.invalidateItems(i,1);
		}
		this.selectedMimeType = null;
	},
	
	showErrorDialog: function(msg) {
		this.controller.showAlertDialog({
			onChoose : function(value) {},
			message: msg,
			choices:
			[{
				label: $L('Close'),
				type: "dismiss",
				value: 'dismissed'
			}]
		});	
	},
	
	handleCommand: function(event) {
		if(event.type == Mojo.Event.command) {
			if (event.command == Mojo.Menu.helpCmd) {
				Event.stop(event);
				var openParams = {
					target: 'http://help.palm.com/device_info/index.html'
				};
				this.controller.serviceRequest('palm://com.palm.applicationManager', {
					method: 'open',
					parameters: {
						id: 'com.palm.app.help',
						params: openParams
					}
				});
			}
		} else if (event.type == Mojo.Event.commandEnable && 
		         (event.command == Mojo.Menu.helpCmd)) {
			event.stopPropagation();
		}
	},
	
	//URL Patterns - Redirect Handlers
	urlPatterns: ["^tel:","^mapto:","^mailto:","^https?:"],
	phoneNumberChoices: [],
	phoneNumberModel: {value: 0,disabled: true},
	addressChoices: [],
	addressesModel: {value: 0,disabled: true},
	emailAddrChoices: [],
	emailAddrModel: {value: 0,disabled: true},
	weblinksChoices: [],
	weblinksModel: {value: 0,disabled: true},
	
	//MIME types - Resource Handlers
	mimeTypes: [],
	fileExtensions: [],
	fileTypes: $H(),
	palmAppNames:$H({"com.palm.app.streamingmusicplayer": $L("Music"), "com.palm.app.videoplayer": $L("Videos"), "com.palm.app.certificate": $L("Certificate Manager")})
});
