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

function AppAssistant(appController){
    this.appController = appController;

    this.defaultRequest = AppAssistant.contactsService.getDefaultAccount(function(resp){
        AppAssistant.defaultAccountId = resp.defaultAccountId;
    }.bind(this));
	
	this.simLengthRequest = new Mojo.Service.Request("palm://com.palm.telephony", {
		method:"simbookEntryMaxLengthQuery",
		parameters:{
			type:"adn"
		},
		onSuccess:function(resp){
			this.simLengthRequest = null;
			if(resp.extended){
				AppAssistant.simNameLength = resp.extended.name;
				AppAssistant.simPhoneLength = resp.extended.number;
			}
		}
	})
    
	this.accountsRequest = AppAssistant.accountsService.getAllAccountsForService(null, null, true, function(resp){
		AppAssistant.accountsList = resp.list;
	}.bind(this), [AccountsService.CONTACTS, AccountsService.IM])
	
	AppAssistant.getIconClass = function(accountId){
		var account =  this.accountsList.find(function(acct){
			return acct.accountId == accountId;
		})
		if(account){
			return account.iconClass;
		} else {
			return "generic"
		}
	}	
    this.handleLaunch = function(params){
        var launchParams = {};
        try {
            launchParams = PalmSystem.launchParams.evalJSON(true);
        } 
        catch (err) {
            Mojo.Log.info("Contacts App: No launch params");
        }
		console.log("Launch Params; " + Object.toJSON(launchParams))
        if (launchParams.launchedAtBoot) {
            Mojo.Log.info("Contacts App: Ignoring initial on-boot launch");
            
			//Ping the pimsync service to let it know that we can receieve notifications
			var pimsyncNotifier = function(){
				new Mojo.Service.Request("palm://com.palm.pimsync", {
					method: 'applicationManagerIsAlive'
				})
			}	
			pimsyncNotifier.delay(30);
			
            // start the contacts service (it does some init work) which in turn starts pimsync (which might resume previously interrupted sync jobs)
            new Mojo.Service.Request(ContactsMojoService.identifier, {
                method: 'ping'
            });
            return;
        }
		
		if(launchParams.launchType == "areYouAwake"){
			new Mojo.Service.Request("palm://com.palm.pimsync", {
					method: 'applicationManagerIsAlive'
				})
				return;
		}

		
		if(launchParams.launchType == "changeLauncherIcon"){
			var params = {
					launchPointId: launchParams.launchPointId,
					icon:launchParams.icon || Contact.DEFAULT_DETAILS_AVATAR
				};
			new Mojo.Service.Request("palm://com.palm.applicationManager", {
				method:"updateLaunchPointIcon",
				parameters: params,
				onSuccess:function(){
					Mojo.Log.info("Updating launch point icon success");
				},
				onFailure:function(e){
					Mojo.Log.error("Updating launch point icon failure %j", e);
				}
			});
			return;
		}
		
        
        if (launchParams.launchType == "passwordInvalid") {
            var messageTemplate = new Template($L("Re-enter your #{domain} password"));
            var bannerParams = {
                bannerText: messageTemplate.evaluate(launchParams)
            }
			var newLaunchParams = Object.extend({}, launchParams);
			newLaunchParams.launchType = "editPassword";
            this.controller.showBanner(messageTemplate.evaluate(launchParams), newLaunchParams, '');
            var passwordStageController = this.controller.getStageController(AppAssistant.PasswordChangedNotification);
		    var f = function(iconClass, accountId, login,stageController){
                stageController.pushScene('passwordchanged', {
					iconClass: iconClass,
					accountId: accountId,
					login:login
				});
            }.bind(this, launchParams.iconClass, launchParams.accountId, launchParams.login);
			if (passwordStageController) {
				f(passwordStageController);
			}
			else {
				var stageparams = {
					name: AppAssistant.PasswordChangedNotification,
					htmlFileName:"notifications"
				};
				this.controller.createStageWithCallback(stageparams, f, 'dashboard');
			}
            return;
        }
        
        var stageController = this.controller.getStageController(AppAssistant.MainStageName);
        if (stageController) {
            /* If it exists, just bring it to the front by focusing its window. */
           
            if (launchParams.launchType || launchParams.id || launchParams.target) {
                this.handleLaunchTypes(stageController, launchParams);
            }
            else {
//                // reset to list view
//				var sceneArguments = {
//					name: "list",
//				};
//				if(stageController.activeScene().sceneName == "list"){
//					sceneArguments.transition = Mojo.Transition.none;
//				}
//                stageController.popScenesTo();
//                stageController.pushScene(sceneArguments, {
//					focusWindow:true
//				});
				stageController.activate();
            }
        }
        else {
            var imageName;
            if (launchParams) {
                if (launchParams.id) imageName = 'images/splash-contacts-edit.png';
                var launchType = launchParams.launchType;
                if (launchType == "editContact") imageName = 'images/splash-contacts-edit.png';
                //else if (launchType == "reminder") imageName = 'images/splash-contacts-reminder.png';
                else if (launchType == "newContact") imageName = 'images/splash-contacts-edit.png';
                //else if (launchType == "editPassword") imageName = 'images/splash-contacts-accountlogin.png';
                else if (launchType == "addToExisting") imageName = 'images/splash-contacts-edit.png';
            }

            var cb = function(launchParams, stageController){
				console.log("calling handleLaunchTypes")
                this.handleLaunchTypes(stageController, launchParams);
            }
            var params = {
                name: AppAssistant.MainStageName,
                lightweight: true,
                splashBackgroundName: imageName
            }
			console.log("Creating a new stage")
            var w = Mojo.Controller.appController.createStageWithCallback(params, cb.bind(this, launchParams));
            return;
        }
    };
    
	this.handleLaunchTypes = function(stageController, launchParams) {
		console.log("Handling launch Types: ");
		var launchType = launchParams.launchType;
		AppAssistant.contactsService.isFirstUse(function(resp) {
			if (resp.firstUse != false && !launchParams.launchType) {
				var that = this;
				launchParams.launchType = "firstUse";
				var gotAccounts = false;
				var gotAccountTypes = false;
				
				var firstUseAttrs = {
					title: $L("Your Contacts Accounts"),
					iconPath:"images/first-launch-contacts-header.png",
					assistant: new FrameworkedFirstUseAssistant()
				}
				var firstUseModel = {};
				
				var pushFirstUse = function () {
					console.log("Pushing it on");
					console.log("Attrs:" + Object.toJSON(firstUseAttrs));
					console.log("Model:" + Object.toJSON(firstUseModel));
					stageController.showFirstLaunchScene(firstUseAttrs, firstUseModel);
					that.finishLaunching(stageController, launchParams);
				}
				var getAccountsCB = function (resp) {
					gotAccounts = true;
					resp.list.each(function (acct) {
						acct.iconPath = Utilities.iconJSONToIconPath(acct.accountSpecificIcons);
						acct.type = acct.iconClass;
						acct.name = acct.login;
						if (acct.domain == 'eas') {
							if (acct.originalLogin) {
								acct.name = acct.originalLogin;
							}
						}
					});
					firstUseModel.accounts = resp.list;
					if (gotAccountTypes) {
						pushFirstUse();
					}
				};
				//keep a reference to this request so it's not garbage-collected
				this.accountRequest = AppAssistant.accountsService.getAllAccountsForService(null, AccountsService.CONTACTS, false, getAccountsCB);
				
				var getAccountTypesCB = function (resp) {
					gotAccountTypes = true;
					
					var accountTypes = {};
					resp.list.each(function (accountType) {
						accountTypes[accountType.domain] = {};
						accountTypes[accountType.domain].title = accountType.name;
						accountTypes[accountType.domain].iconClass = accountType.iconClass;
						accountTypes[accountType.domain].id = accountType.id;
						accountTypes[accountType.domain].domain = accountType.domain;
					});
					
					firstUseAttrs.accountTypes = accountTypes;
					if (gotAccounts) {
						pushFirstUse();
					}
				};
				//keep a reference to this request so it's not garbage-collected
				this.accountTypeRequest = new Mojo.Service.Request('palm://com.palm.accounts/', {
					method: 'getAllAccountTypesForService',
					parameters: { service: 'CONTACTS' },
					onSuccess: getAccountTypesCB
				});
			} else {
				this.finishLaunching(stageController, launchParams);
			}
		}.bind(this));
    }.bind(this);
	
	this.finishLaunching = function(stageController, launchParams) {
		var shouldFocus = !stageController.active;
		var transition = Mojo.Transition.defaultTransition;
		if (shouldFocus) {
			transition = Mojo.Transition.none;
		} else {
			//Do this even when teh card is active because this is what tells the 
			//launcher to close itself.
			stageController.activate();
		}
		var launchType = launchParams.launchType;
		if (launchType != "firstUse") {
			//Check to see if the details view is already up and at the contact we want
			if (launchParams.id) {
				var topScene = stageController.topScene();
				if (topScene && topScene.assistant["detailViewIsUpWithPersonId"]) {
					if (topScene.assistant["detailViewIsUpWithPersonId"](launchParams.id)) {
						stageController.activate();
						return;
					}
				}
			}
			
			stageController.popScenesTo();
			var listSceneArgs = {
				name:"list",
				transition:transition
			};
			stageController.pushScene(listSceneArgs);
		}
		
		if (launchParams.id) {
			stageController.pushScene({
				name: "detail",
				transition: transition
			}, {
				personId: launchParams.id,
				launchType: launchType,
				focusWindow: shouldFocus
			});
			return;
		}
		//if((launchParams.target && launchParams.target.indexOf(".vcf") != -1) || launchParams.mime == "text/x-vcard"){
		if (launchParams.target) {
			var vcardSuccess = function (resp) {
				this.vcardRequest = null;
				console.log("vcard Resonse is : " + Object.toJSON(resp));
				stageController.activate();
				var delay = function () {
					if (resp.count == 1) {
						this.vcardRequest = new Mojo.Service.Request("palm://com.palm.contacts", {
							method: "readVCard",
							parameters: {
								filePath: launchParams.target
							},
							onSuccess: function (vcardInfo) {
								Pseudocard.pushPseudocard(stageController, {
									contact: vcardInfo.contacts[0]
								});
							}
						});
					} else {
						var obj = {
							count: resp.count
						};
						console.log("Showing alert dialog");
						stageController.topScene().showAlertDialog({
							message: $L("Would you like to import #{count} contacts?  This could take a few minutes.").interpolate(obj),
							choices: [{
								label: $L("OK"),
								value: "ok"
							}, {
								label: $L("Cancel"),
								type: "negative",
								value: "negatory"
							}],
							onChoose: function (command) {
								console.log("Command was : " + command);
								if (command != "ok") {
									return;
								}
								Mojo.Controller.getAppController().showBanner($L("Importing VCard..."), null, null);
								this.vcardRequest = new Mojo.Service.Request("palm://com.palm.contacts", {
									method: "importVCard",
									parameters: {
										filePath: launchParams.target
									},
									onSuccess: function (resp) {
										var obj = {
											successes: resp.count
										}
										Mojo.Controller.getAppController().showBanner($L("#{successes} contacts imported").interpolate(obj), null, null);
									}
								});
							}.bind(this)
						});
					}
				}.bind(this);
				delay.defer();
			}.bind(this);
			var vcardFailure = function () {
				console.log("FAILED!");
				stageController.activate();
				stageController.delegateToSceneAssistant.bind(stageController, "showErrorMessage", $L("There was a problem reading this vcard.")).defer()
			}.bind(this);
			this.vcardRequest = new Mojo.Service.Request("palm://com.palm.contacts", {
				method: "countVCardContacts",
				parameters: {
					filePath: launchParams.target
				}, 
				onSuccess: vcardSuccess,
				onFailure: vcardFailure
			});
		}
		
		if (launchType == "editContact") {
			stageController.pushScene({
				name: "edit",
				transition: transition
			}, {
				personIdToSwapTo: launchParams.personId,
				linkedContacts: launchParams.linkedContacts,
				person: launchParams.person,
				focusWindow: shouldFocus
			});
			return;
		}
        
		if (launchType == "reminder") {
			stageController.pushScene({
				name: "detail",
				transition: transition
			}, {
				personId: launchParams.personId,
			});
			stageController.pushScene({
				name: "reminder",
				transition: transition
			}, {
				personId: launchParams.personId,
				focusWindow: shouldFocus,
				focusField: launchParams.focusField,
				hasReminderTextToLoad: true
			});
		}
		
		if (launchType == "newContact") {
			var c = launchParams.contact;
			c.dirty = true;
			stageController.pushScene({
				name: "edit",
				transition: transition
			}, {
				launchToEditMode: true,
				newContact: true,
				contact: c,
				focusWindow: shouldFocus
			});
			return;
        }
		
		if(launchType == "editPassword"){
			this.controller.closeStage(AppAssistant.PasswordChangedNotification);
			stageController.pushScene({
				name:"prefs",
				transition:transition
			})
			var loginParams = {
				acctId : launchParams.accountId,
				acctLogin : launchParams.login,
				acctTypeId : null,
				acctDomain : launchParams.domain,
				acctName : launchParams.accountDisplayName,
				iconClass:launchparams.iconClass,
				numberOfTimesToPopScene: 1
			}
			 stageController.pushScene({
				name: "accountlogin",
				transition: transition
			}, launchParams.accountId, launchParams.login, null, launchParams.domain, launchParams.accountDisplayName, null, launchParams.iconClass, true);
			return;
		}
        
        if (launchType == "pseudo-card") {
            var c = launchParams.contact;
			Pseudocard.pushPseudocard(stageController, {
                contact: c,
				focusWindow:shouldFocus
            });
			return;
        }
        
        if (launchType == "addToExisting") {
            var c = launchParams.contact;
            var cb = function(existingPerson){
				stageController.delegateToSceneAssistant("showListSavingScrim")
				c = new Contact(c);
				
				var switchToDetails = function(resp){
					this.saveRequest = null;
					if (stageController.activeScene().sceneName == "picker") {
                            stageController.swapScene("detail", {
                        	personId: resp.personId
                    	});
                    }
				}.bind(this)
				
				var afterGetLinked = function(linkedContactsResponse){
					var contactToAddTo = null;
					var contactToCopyFrom = null;
					var linkedContacts = linkedContactsResponse.list;
					linkedContacts.each(function(linkedContact){
						if(!linkedContact.readOnly){
							if (!contactToAddTo) {
								contactToAddTo = linkedContact;
							}
							if (linkedContact.accountId == AppAssistant.defaultAccountId) {
								contactToAddTo = linkedContact;
								throw $break;
							}
						} else {
							contactToCopyFrom = linkedContact;
						}
					})
                    
                    if (!contactToAddTo) {
						contactToCopyFrom = new Contact(contactToCopyFrom)
                        if (!c.getFullName() || c.getFullName().blank()) {
                            c.setFullName(contactToCopyFrom.getFullName());
                        }
                        if (!c.accountId) {
                            c.accountId = AppAssistant.defaultAccountId;
                        }
						
						var saveSuccess = function(newContactInfo){
                            this.addToExistingSaveRequest = null;
                            AppAssistant.contactsService.linkContacts(null, existingPerson.personId, [newContactInfo.personId]);
                            switchToDetails(existingPerson);
                        }.bind(this);
						
						var saveFailure = function(){
							if(stageController.activeScene().sceneName == "picker"){
								stageController.popScene();
							}
							stageController.delegateToSceneAssistant.bind(stageController, "showErrorMessage", $L("There was an error adding this information.")).defer()
						}.bind(this);
						
                        this.addToExistingSaveRequest = AppAssistant.contactsService.save(c, saveSuccess, saveFailure);
                    } else {
						Contact.copyContactPoints(contactToAddTo, c);
						var saveFailure = function(){
							if(stageController.activeScene().sceneName == "picker"){
								stageController.popScene();
							}
							stageController.delegateToSceneAssistant.bind(stageController, "showErrorMessage", $L("There was an error adding this information.")).defer();
						}.bind(this);
						this.saveRequest = AppAssistant.contactsService.save(contactToAddTo, switchToDetails, saveFailure);
					}
					
					
				}.bind(this)
				
				
				
				var getLinkedFailed = function(){
					if(stageController.activeScene().sceneName == "picker"){
						stageController.popScene();
					}
					stageController.delegateToSceneAssistant.bind(stageController, "showErrorMessage", $L("There was an error adding this information.")).defer();
					Mojo.Log.error("Get linked contacts failed when trying to add to existing contact")
				}
				
				AppAssistant.contactsService.getLinkedContacts(existingPerson.personId, afterGetLinked, undefined, getLinkedFailed, true);


            }.bind(this)
            stageController.pushScene({
				name: "list",
				transition: transition
			}, {
                message: $L("Link to an existing contact"),
                mode: "picker",
                callback: cb,
				focusWindow:shouldFocus,
				suppressPopScene:true
            });
			return;
        }
    }
    
    this.handleCommand = function(event){
        if (event.type == Mojo.Event.commandEnable) {
            if (event.command == Mojo.Menu.helpCmd) {
                event.stopPropagation();
            }
        }
        if (event.type == Mojo.Event.command) {
            if (event.command === Mojo.Menu.helpCmd) {
                MenuHandler.launchHelp();
                event.stop();
            }
        }
    };
}

function StageAssistant(stageController){
}

// alias the service
AppAssistant.contactsService = new ContactsMojoService;
AppAssistant.pimSyncService = new PIMSyncMojoService;
AppAssistant.accountsService = new AccountsService;
AppAssistant.MainStageName = "contacts";
AppAssistant.PasswordChangedNotification = "PasswordChangedNotification";
// When the Prefs scene alters the sort order, any list view present needs to completely clear its cache and reset.  The Prefs scene will call this fn if defined to reset the list.
AppAssistant.listResetCallback = undefined;
