home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / mail.xpi / bin / chrome / messenger.jar / content / messenger / AccountWizard.js < prev    next >
Encoding:
JavaScript  |  2001-10-02  |  30.9 KB  |  909 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  */
  20.  
  21. /* the okCallback is used for sending a callback for the parent window */
  22. var okCallback = null;
  23. /* The account wizard creates new accounts */
  24.  
  25. /*
  26.   data flow into the account wizard like this:
  27.  
  28.   For new accounts:
  29.   * pageData -> Array -> createAccount -> finishAccount
  30.   
  31.   For accounts coming from the ISP setup:
  32.   * RDF  -> Array -> pageData -> Array -> createAccount -> finishAccount
  33.   
  34.   for "unfinished accounts" 
  35.   * account -> Array -> pageData -> Array -> finishAccount
  36.   
  37.   Where:
  38.   pageData - the actual pages coming out of the Widget State Manager
  39.   RDF      - the ISP datasource
  40.   Array    - associative array of attributes, that very closely
  41.              resembles the nsIMsgAccount/nsIMsgIncomingServer/nsIMsgIdentity
  42.              structure
  43.   createAccount() - creates an account from the above Array
  44.   finishAccount() - fills an existing account with data from the above Array 
  45.  
  46. */
  47.  
  48. /* 
  49.    the account wizard path is something like:
  50.    
  51.    accounttype -> identity -> server -> login -> accname -> done
  52.                              \-> newsserver ----/
  53.  
  54.    where the accounttype determines which path to take
  55.    (server vs. newsserver)
  56. */
  57.  
  58. var gWizardMap = {
  59.     accounttype: { next: "identity" },
  60.     identity: { previous: "accounttype"}, // don't define next: server/newsserver
  61.     server:   { next: "login", previous: "identity"},
  62.     newsserver: { next: "accname", previous: "identity"},
  63.     login:    { next: "accname", previous: "server"}, 
  64.     accname:  { next: "done", }, // don't define previous: login/newsserver
  65.     done:     { previous: "accname", finish: true }
  66. }
  67.  
  68. var pagePrefix="chrome://messenger/content/aw-";
  69. var pagePostfix=".xul";
  70.  
  71. var currentPageTag;
  72.  
  73. var contentWindow;
  74.  
  75. var smtpService;
  76. var am;
  77. var accountm = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  78.  
  79. var accounts = accountm.accounts;
  80.  
  81. //accountCount indicates presence or absense of accounts
  82. var accountCount = accounts.Count();
  83.  
  84. var nsIMsgIdentity = Components.interfaces.nsIMsgIdentity;
  85. var nsIMsgIncomingServer = Components.interfaces.nsIMsgIncomingServer;
  86. var gPrefsBundle, gMessengerBundle;
  87. var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
  88. promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
  89.  
  90. // the current nsIMsgAccount
  91. var gCurrentAccount;
  92.  
  93. // default account
  94. var gDefaultAccount;
  95.  
  96. // the current associative array that
  97. // will eventually be dumped into the account
  98. var gCurrentAccountData;
  99.  
  100. // default picker mode for copies and folders
  101. gDefaultSpecialFolderPickerMode = "0";
  102.  
  103. // event handlers
  104. function onLoad() {
  105.     gPrefsBundle = document.getElementById("bundle_prefs");
  106.     gMessengerBundle = document.getElementById("bundle_messenger");
  107.  
  108.     // wizard stuff
  109.     // instantiate the Wizard Manager
  110.     wizardManager = new WizardManager( "wizardContents", null, null,
  111.                                        gWizardMap );
  112.     wizardManager.URL_PagePrefix = "chrome://messenger/content/aw-";
  113.     wizardManager.URL_PagePostfix = ".xul"; 
  114.     wizardManager.SetHandlers(null, null, onFinish, onCancel, null, null);
  115.     
  116.     /* We are checking here for the callback argument */
  117.     if (window.arguments && window.arguments[0])
  118.         if(window.arguments[0].okCallback ) 
  119.         {
  120. //            dump("There is okCallback");
  121.             top.okCallback = window.arguments[0].okCallback;
  122.         }
  123.  
  124.     // load up the SMTP service for later
  125.     if (!smtpService) {
  126.         smtpService =
  127.             Components.classes["@mozilla.org/messengercompose/smtp;1"].getService(Components.interfaces.nsISmtpService);
  128.     }
  129.  
  130.     checkForInvalidAccounts();
  131.     var pageData = GetPageData();
  132.     updateMap(pageData, gWizardMap);
  133.  
  134.     // skip the first page if we have an account
  135.     if (gCurrentAccount) {
  136.         // skip past first pane
  137.         gWizardMap.identity.previous = null;
  138.         wizardManager.LoadPage("identity", false);
  139.     }
  140.     else
  141.         wizardManager.LoadPage("accounttype", false);
  142.     
  143.     try {
  144.       gDefaultAccount = accountm.defaultAccount;
  145.     }
  146.     catch (ex) {
  147.       // no default account, this is expected the first time you launch mail
  148.       // on a new profile
  149.       gDefaultAccount = null;
  150.     }
  151. }
  152.  
  153.     
  154. function onCancel() 
  155. {
  156.   var firstInvalidAccount = getFirstInvalidAccount();
  157.  
  158.   // if the user cancels the the wizard when it pops up because of 
  159.   // an invalid account (example, a webmail account that activation started)
  160.   // we just force create it by setting some values and calling the FinishAccount()
  161.   // see bug #47521 for the full discussion
  162.   if (firstInvalidAccount) {
  163.     var pageData = GetPageData();
  164.     // set the fullName if it doesn't exist
  165.     if (!pageData.identity.fullName || !pageData.identity.fullName.value) {
  166.       setPageData(pageData, "identity", "fullName", "");
  167.     }
  168.  
  169.     // set the email if it doesn't exist
  170.     if (!pageData.identity.email || !pageData.identity.email.value) {
  171.       setPageData(pageData, "identity", "email", "user@domain.invalid");
  172.     }
  173.  
  174.     // call FinishAccount() and not onFinish(), since the "finish"
  175.     // button may be disabled
  176.     FinishAccount();
  177.   }
  178.   else {
  179.     // since this is not an invalid account
  180.     // really cancel if the user hits the "cancel" button
  181.     if (accountCount < 1) {
  182.       var confirmMsg = gPrefsBundle.getString("cancelWizard");
  183.       var confirmTitle = gPrefsBundle.getString("accountWizard");
  184.       var result = {value:0};
  185.  
  186.       promptService.confirmEx(window, confirmTitle, confirmMsg,
  187.         (promptService.BUTTON_TITLE_IS_STRING*promptService.BUTTON_POS_0)+
  188.         (promptService.BUTTON_TITLE_IS_STRING*promptService.BUTTON_POS_1),
  189.         gPrefsBundle.getString('WizardExit'),
  190.         gPrefsBundle.getString('WizardContinue'), 
  191.         null, null, {value:0}, result);
  192.  
  193.       if (result.value == 0)
  194.         window.close();
  195.     }
  196.     else
  197.       window.close();
  198.  
  199.     if(top.okCallback) {
  200.       var state = false;
  201.       top.okCallback(state);
  202.     }
  203.   }
  204. }
  205.  
  206. function onFinish() {
  207.     if( !wizardManager.wizardMap[wizardManager.currentPageTag].finish )
  208.         return;
  209.  
  210.     FinishAccount();
  211. }
  212.     
  213. function FinishAccount() {
  214.     var pageData = GetPageData();
  215.  
  216.     dump(parent.wizardManager.WSM);
  217.  
  218.     var accountData= gCurrentAccountData;
  219.     
  220.     if (!accountData)
  221.     {
  222.       accountData = new Object;
  223.       // Time to set the smtpRequiresUsername attribute
  224.       if (!serverIsNntp(pageData))
  225.         accountData.smtpRequiresUsername = true;
  226.     }
  227.     
  228.     PageDataToAccountData(pageData, accountData);
  229.  
  230.     FixupAccountDataForIsp(accountData);
  231.     
  232.     // we might be simply finishing another account
  233.     if (!gCurrentAccount)
  234.         gCurrentAccount = createAccount(accountData);
  235.  
  236.     // transfer all attributes from the accountdata
  237.     finishAccount(gCurrentAccount, accountData);
  238.     
  239.     verifyLocalFoldersAccount(gCurrentAccount);
  240.  
  241.     if (!serverIsNntp(pageData))
  242.         EnableCheckMailAtStartUpIfNeeded(gCurrentAccount);
  243.  
  244.     // in case we crash, force us a save of the prefs file NOW
  245.     try {
  246.       am.saveAccountInfo();
  247.     } 
  248.     catch (ex) {
  249.       dump("Error saving account info: " + ex + "\n");
  250.     }
  251.     window.close();
  252.     if(top.okCallback)
  253.     {
  254.         var state = true;
  255.         //dump("finish callback");
  256.         top.okCallback(state);
  257.     }
  258. }
  259.  
  260.  
  261. // prepopulate pageData with stuff from accountData
  262. // use: to prepopulate the wizard with account information
  263. function AccountDataToPageData(accountData, pageData)
  264. {
  265.     if (!accountData) {
  266.         dump("null account data! clearing..\n");
  267.         // handle null accountData as if it were an empty object
  268.         // so that we clear-out any old pagedata from a
  269.         // previous accountdata. The trick is that
  270.         // with an empty object, accountData.identity.slot is undefined,
  271.         // so this will clear out the prefill data in setPageData
  272.         
  273.         accountData = new Object;
  274.         accountData.incomingServer = new Object;
  275.         accountData.identity = new Object;
  276.         accountData.smtp = new Object;
  277.     }
  278.     
  279.     var server = accountData.incomingServer;
  280.  
  281.     if (server.type == undefined) {
  282.         // clear out the old server data
  283.         //setPageData(pageData, "accounttype", "mailaccount", undefined);
  284.         //        setPageData(pageData, "accounttype", "newsaccount", undefined);
  285.         setPageData(pageData, "server", "servertype", undefined);
  286.         setPageData(pageData, "server", "hostname", undefined);
  287.         
  288.     } else {
  289.         
  290.         if (server.type == "nntp") {
  291.             setPageData(pageData, "accounttype", "newsaccount", true);
  292.             setPageData(pageData, "newsserver", "hostname", server.hostName);
  293.         }
  294.         
  295.         else {
  296.             setPageData(pageData, "accounttype", "mailaccount", true);
  297.             setPageData(pageData, "server", "servertype", server.type);
  298.             setPageData(pageData, "server", "hostname", server.hostName);
  299.         }
  300.     }
  301.     
  302.     setPageData(pageData, "login", "username", server.username);
  303.     setPageData(pageData, "login", "password", server.password);
  304.     setPageData(pageData, "login", "rememberPassword", server.rememberPassword);
  305.     setPageData(pageData, "accname", "prettyName", server.prettyName);
  306.     
  307.     var identity;
  308.     
  309.     if (accountData.identity) {
  310.         dump("This is an accountdata\n");
  311.         identity = accountData.identity;
  312.     }
  313.     else if (accountData.identities) {
  314.         identity = accountData.identities.QueryElementAt(0, Components.interfaces.nsIMsgIdentity);
  315.         dump("this is an account, id= " + identity + "\n");
  316.     } 
  317.  
  318.     setPageData(pageData, "identity", "email", identity.email);
  319.     setPageData(pageData, "identity", "fullName", identity.fullName);
  320.  
  321.     var smtp;
  322.     
  323.     if (accountData.smtp) {
  324.         smtp = accountData.smtp;
  325.         setPageData(pageData, "server", "smtphostname",
  326.                     smtp.hostname);
  327.     }
  328. }
  329.  
  330. // take data from each page of pageData and dump it into accountData
  331. // use: to put results of wizard into a account-oriented object
  332. function PageDataToAccountData(pageData, accountData)
  333. {
  334.     if (!accountData.identity)
  335.         accountData.identity = new Object;
  336.     if (!accountData.incomingServer)
  337.         accountData.incomingServer = new Object;
  338.     if (!accountData.smtp)
  339.         accountData.smtp = new Object;
  340.     
  341.     var identity = accountData.identity;
  342.     var server = accountData.incomingServer;
  343.     var smtp = accountData.smtp;
  344.  
  345.     dump("Setting identity for " + pageData.identity.email.value + "\n");
  346.     identity.email = pageData.identity.email.value;
  347.     identity.fullName = pageData.identity.fullName.value;
  348.  
  349.     server.type = getCurrentServerType(pageData);
  350.     server.hostName = getCurrentHostname(pageData);
  351.  
  352.     if (serverIsNntp(pageData)) {
  353.         // this stuff probably not relevant
  354.         dump("not setting username/password/rememberpassword/etc\n");
  355.     } else {
  356.         if (pageData.login) {
  357.             if (pageData.login.username)
  358.                 server.username = pageData.login.username.value;
  359.             if (pageData.login.password)
  360.                 server.password = pageData.login.password.value;
  361.             if (pageData.login.rememberPassword)
  362.                 server.rememberPassword = pageData.login.rememberPassword.value;
  363.         }
  364.  
  365.         dump("pageData.server = " + pageData.server + "\n");
  366.         if (pageData.server) {
  367.             dump("pageData.server.smtphostname.value = " + pageData.server.smtphostname + "\n");
  368.             if (pageData.server.smtphostname &&
  369.                 pageData.server.smtphostname.value)
  370.                 smtp.hostname = pageData.server.smtphostname.value;
  371.         }
  372.     }
  373.  
  374.     if (pageData.accname) {
  375.         if (pageData.accname.prettyName)
  376.             server.prettyName = pageData.accname.prettyName.value;
  377.     }
  378.  
  379. }
  380.  
  381. // given an accountData structure, create an account
  382. // (but don't fill in any fields, that's for finishAccount()
  383. function createAccount(accountData)
  384. {
  385.  
  386.     var server = accountData.incomingServer;
  387.     dump("am.createIncomingServer(" + server.username + "," +
  388.                                       server.hostName + "," +
  389.                                       server.type + ")\n");
  390.     var server = am.createIncomingServer(server.username,
  391.                                          server.hostName,
  392.                                          server.type);
  393.     
  394.     dump("am.createIdentity()\n");
  395.     var identity = am.createIdentity();
  396.     
  397.     /* new nntp identities should use plain text by default
  398.      * we want that GNKSA (The Good Net-Keeping Seal of Approval) */
  399.     if (server.type == "nntp") {
  400.             identity.composeHtml = false;
  401.     }
  402.  
  403.     dump("am.createAccount()\n");
  404.     var account = am.createAccount();
  405.     account.addIdentity(identity);
  406.     account.incomingServer = server;
  407.     return account;
  408. }
  409.  
  410. // given an accountData structure, copy the data into the
  411. // given account, incoming server, and so forth
  412. function finishAccount(account, accountData) {
  413.  
  414.     if (accountData.incomingServer) {
  415.  
  416.         var destServer = account.incomingServer;
  417.         var srcServer = accountData.incomingServer;
  418.         copyObjectToInterface(destServer, srcServer);
  419.  
  420.         // see if there are any protocol-specific attributes
  421.         // if so, we use the type to get the IID, QueryInterface
  422.         // as appropriate, then copy the data over
  423.         dump("srcServer.ServerType-" + srcServer.type + " = " +
  424.              srcServer["ServerType-" + srcServer.type] + "\n");
  425.         if (srcServer["ServerType-" + srcServer.type]) {
  426.             // handle server-specific stuff
  427.             var IID = getInterfaceForType(srcServer.type);
  428.             if (IID) {
  429.                 destProtocolServer = destServer.QueryInterface(IID);
  430.                 srcProtocolServer = srcServer["ServerType-" + srcServer.type];
  431.  
  432.                 dump("Copying over " + srcServer.type + "-specific data\n");
  433.                 copyObjectToInterface(destProtocolServer, srcProtocolServer);
  434.             }
  435.         }
  436.         account.incomingServer.valid=true;
  437.     }
  438.  
  439.     // copy identity info
  440.     var destIdentity =
  441.         account.identities.QueryElementAt(0, nsIMsgIdentity);
  442.     
  443.     if (accountData.identity && destIdentity) {
  444.  
  445.         // fixup the email address if we have a default domain
  446.         var emailArray = accountData.identity.email.split('@');
  447.         if (emailArray.length < 2 && accountData.domain) {
  448.             accountData.identity.email += '@' + accountData.domain;
  449.         }
  450.  
  451.         copyObjectToInterface(destIdentity,
  452.                               accountData.identity);
  453.         destIdentity.valid=true;
  454.     }
  455.  
  456.     // don't try to create an smtp server if we already have one.
  457.     if (!destIdentity.smtpServerKey)
  458.     {
  459.         var smtpServer;
  460.         
  461.         /**
  462.          * Create a new smtp server if needed. If smtpCreateNewServer pref
  463.          * is set then createSmtpServer routine() will create one. Otherwise,
  464.          * default server is returned which is also set to create a new smtp server
  465.          * (via GetDefaultServer()) if no default server is found.
  466.          */
  467.         if (accountData.smtp.hostname != null)
  468.           smtpServer = smtpService.createSmtpServer();
  469.         else
  470.           smtpServer = smtpService.defaultServer;
  471.  
  472.         dump("Copying smtpServer (" + smtpServer + ") to accountData\n");
  473.         //set the smtp server to be the default only if it is not a redirectorType
  474.         if (accountData.smtp.redirectorType == null)
  475.           smtpService.defaultServer = smtpServer;
  476.  
  477.         copyObjectToInterface(smtpServer, accountData.smtp);
  478.  
  479.         // some identities have 'preferred' 
  480.         if (accountData.smtpUsePreferredServer && destIdentity)
  481.             destIdentity.smtpServerKey = smtpServer.key;
  482.      }
  483.  
  484.      if (this.FinishAccountHook != undefined) {
  485.          FinishAccountHook(accountData.domain);
  486.      }
  487. }
  488.  
  489.  
  490. // copy over all attributes from dest into src that already exist in src
  491. // the assumption is that src is an XPConnect interface full of attributes
  492. function copyObjectToInterface(dest, src) {
  493.     if (!dest) return;
  494.     if (!src) return;
  495.  
  496.     var i;
  497.     for (i in src) {
  498.         try {
  499.             if (dest[i] != src[i])
  500.                 dest[i] = src[i];
  501.         }
  502.         catch (ex) {
  503.             dump("Error copying the " +
  504.                  i + " attribute: " + ex + "\n");
  505.             dump("(This is ok if this is a ServerType-* attribute)\n");
  506.         }
  507.     }
  508. }
  509.  
  510. // check if there already is a "Local Folders"
  511. // if not, create it.
  512. function verifyLocalFoldersAccount(account) {
  513.     
  514.     dump("Looking for Local Folders.....\n");
  515.     var localMailServer = null;
  516.     try {
  517.         localMailServer = am.localFoldersServer;
  518.     }
  519.     catch (ex) {
  520.         // dump("exception in findserver: " + ex + "\n");
  521.         localMailServer = null;
  522.     }
  523.  
  524.     try {
  525.     var server = account.incomingServer;
  526.     var identity = account.identities.QueryElementAt(0, Components.interfaces.nsIMsgIdentity);
  527.  
  528.     // for this server, do we default the folder prefs to this server, or to the "Local Folders" server
  529.     var defaultCopiesAndFoldersPrefsToServer = server.defaultCopiesAndFoldersPrefsToServer;
  530.  
  531.     if (!localMailServer) {
  532.             // dump("Creating local mail account\n");
  533.         // creates a copy of the identity you pass in
  534.             messengerMigrator = Components.classes["@mozilla.org/messenger/migrator;1"].getService(Components.interfaces.nsIMessengerMigrator);
  535.         messengerMigrator.createLocalMailAccount(false /* false, since we are not migrating */);
  536.         try {
  537.             localMailServer = am.localFoldersServer;
  538.         }
  539.         catch (ex) {
  540.             dump("error!  we should have found the local mail server after we created it.\n");
  541.             localMailServer = null;
  542.         }    
  543.         }
  544.  
  545.     var copiesAndFoldersServer = null;
  546.     if (defaultCopiesAndFoldersPrefsToServer) {
  547.         copiesAndFoldersServer = server;
  548.     }
  549.     else {
  550.         if (!localMailServer) {
  551.             dump("error!  we should have a local mail server at this point\n");
  552.             return;
  553.         }
  554.         copiesAndFoldersServer = localMailServer;
  555.     }
  556.     
  557.     setDefaultCopiesAndFoldersPrefs(identity, copiesAndFoldersServer);
  558.  
  559.     } catch (ex) {
  560.         // return false (meaning we did not create the account)
  561.         // on any error
  562.         dump("Error creating local mail: " + ex + "\n");
  563.         return false;
  564.     }
  565.     return true;
  566. }
  567.  
  568. function setDefaultCopiesAndFoldersPrefs(identity, server)
  569. {
  570.     dump("finding folders on server = " + server.hostName + "\n");
  571.  
  572.     var rootFolder = server.RootFolder;
  573.  
  574.     // we need to do this or it is possible that the server's draft,
  575.     // stationery fcc folder will not be in rdf
  576.     //
  577.     // this can happen in a couple cases
  578.     // 1) the first account we create, creates the local mail.  since
  579.     // local mail was just created, it obviously hasn't been opened,
  580.     // or in rdf..
  581.     // 2) the account we created is of a type where
  582.     // defaultCopiesAndFoldersPrefsToServer is true
  583.     // this since we are creating the server, it obviously hasn't been
  584.     // opened, or in rdf.
  585.     //
  586.     // this makes the assumption that the server's draft, stationery fcc folder
  587.     // are at the top level (ie subfolders of the root folder.)  this works
  588.     // because we happen to be doing things that way, and if the user changes
  589.     // that, it will work because to change the folder, it must be in rdf,
  590.     // coming from the folder cache, in the worst case.
  591.     var folders = rootFolder.GetSubFolders();
  592.     var msgFolder = rootFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
  593.     var numFolders = new Object();
  594.  
  595.     var protocolInfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + msgFolder.server.type].getService(Components.interfaces.nsIMsgProtocolInfo);
  596.  
  597.     /** 
  598.      * Check if this protocol service needs to create special folder URIs.
  599.      * In case of IMAP, when a new account is created, folders 'Sent', 'Drafts'
  600.      * and 'Templates' are not created then, but created on demand at runtime. 
  601.      * But we do need to present them as possible choices in the Copies and Folders 
  602.      * UI. To do that, folder URIs have to be created and stored in the prefs file. 
  603.      * So, if there is a need to build special folders, append the special folder 
  604.      * names and create right URIs.
  605.      */
  606.     if (protocolInfo.needToBuildSpecialFolderURIs)
  607.     {
  608.         var folderDelim = "/";
  609.         var sentFolderName =  gMessengerBundle.getString("sentFolderName");
  610.         var draftsFolderName =  gMessengerBundle.getString("draftsFolderName");
  611.         var templatesFolderName =  gMessengerBundle.getString("templatesFolderName");
  612.  
  613.         identity.draftFolder = msgFolder.server.serverURI+ folderDelim + draftsFolderName;
  614.         identity.stationeryFolder = msgFolder.server.serverURI+ folderDelim + templatesFolderName;
  615.         identity.fccFolder = msgFolder.server.serverURI+ folderDelim + sentFolderName;
  616.     }
  617.     else {
  618.         // these hex values come from nsMsgFolderFlags.h
  619.     var draftFolder = msgFolder.getFoldersWithFlag(0x0400, 1, numFolders);
  620.     var stationeryFolder = msgFolder.getFoldersWithFlag(0x400000, 1, numFolders);
  621.     var fccFolder = msgFolder.getFoldersWithFlag(0x0200, 1, numFolders);
  622.  
  623.     if (draftFolder) identity.draftFolder = draftFolder.URI;
  624.     if (stationeryFolder) identity.stationeryFolder = stationeryFolder.URI;
  625.     if (fccFolder) identity.fccFolder = fccFolder.URI;
  626.  
  627.     dump("fccFolder = " + identity.fccFolder + "\n");
  628.     dump("draftFolder = " + identity.draftFolder + "\n");
  629.     dump("stationeryFolder = " + identity.stationeryFolder + "\n");
  630.     }
  631.     
  632.     identity.fccFolderPickerMode = gDefaultSpecialFolderPickerMode;
  633.     identity.draftsFolderPickerMode = gDefaultSpecialFolderPickerMode;
  634.     identity.tmplFolderPickerMode = gDefaultSpecialFolderPickerMode;
  635. }
  636.  
  637. function AccountExists(userName,hostName,serverType)
  638. {
  639.   var accountExists = false;
  640.   var accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  641.   try {
  642.         var server = accountManager.FindServer(userName,hostName,serverType);
  643.         if (server) {
  644.                 accountExists = true;
  645.         }
  646.   }
  647.   catch (ex) {
  648.         accountExists = false;
  649.   }
  650.   return accountExists;
  651. }
  652.  
  653. function getFirstInvalidAccount()
  654. {
  655.     am = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  656.  
  657.     var invalidAccounts = getInvalidAccounts(am.accounts);
  658.   
  659.     if (invalidAccounts.length > 0)
  660.         return invalidAccounts[0];
  661.     else
  662.         return null;
  663. }
  664.  
  665. function checkForInvalidAccounts()
  666. {
  667.     var firstInvalidAccount = getFirstInvalidAccount();
  668.  
  669.     if (firstInvalidAccount) {
  670.         var pageData = GetPageData();
  671.         dump("We have an invalid account, " + firstInvalidAccount + ", let's use that!\n");
  672.         gCurrentAccount = firstInvalidAccount;
  673.  
  674.         // there's a possibility that the invalid account has ISP defaults
  675.         // as well.. so first pre-fill accountData with ISP info, then
  676.         // overwrite it with the account data
  677.  
  678.  
  679.         var identity =
  680.             firstInvalidAccount.identities.QueryElementAt(0, nsIMsgIdentity);
  681.  
  682.         dump("Invalid account: trying to get ISP data for " + identity.email + "\n");
  683.         var accountData = getIspDefaultsForEmail(identity.email);
  684.         dump("Invalid account: Got " + accountData + "\n");
  685.         
  686.         // account -> accountData -> pageData
  687.         accountData = AccountToAccountData(firstInvalidAccount, accountData);
  688.         
  689.         AccountDataToPageData(accountData, pageData);
  690.  
  691.         gCurrentAccountData = accountData;
  692.         
  693.         dump(parent.wizardManager.WSM);
  694.     }
  695. }
  696.  
  697. function AccountToAccountData(account, defaultAccountData)
  698. {
  699.     dump("AccountToAccountData(" + account + ", " +
  700.          defaultAccountData + ")\n");
  701.     var accountData = defaultAccountData;
  702.     if (!accountData)
  703.         accountData = new Object;
  704.     
  705.     accountData.incomingServer = account.incomingServer;
  706.     accountData.identity = account.identities.QueryElementAt(0, nsIMsgIdentity);
  707.     accountData.smtp = smtpService.defaultServer;
  708.  
  709.     return accountData;
  710. }
  711.  
  712.  
  713. // sets the page data, automatically creating the arrays as necessary
  714. function setPageData(pageData, tag, slot, value) {
  715.     if (!pageData[tag]) pageData[tag] = [];
  716.  
  717.     if (value == undefined) {
  718.         // clear out this slot
  719.         if (pageData[tag][slot]) delete pageData[tag][slot];
  720.     } else {
  721.         // pre-fill this slot
  722.         if (!pageData[tag][slot]) pageData[tag][slot] = [];
  723.         pageData[tag][slot].id = slot;
  724.         pageData[tag][slot].value = value;
  725.     }
  726. }
  727.  
  728. // value of checkbox on the first page
  729. function serverIsNntp(pageData) {
  730.     if (pageData.accounttype.newsaccount)
  731.         return pageData.accounttype.newsaccount.value;
  732.     return false;
  733. }
  734.  
  735. function getUsernameFromEmail(email)
  736. {
  737.     var emailData = email.split("@");
  738.     return emailData[0];
  739. }
  740.  
  741. function getCurrentUserName(pageData)
  742. {
  743.     var userName = "";
  744.  
  745.     if (pageData.login) {
  746.         if (pageData.login.username) {
  747.             userName = pageData.login.username.value;
  748.         }
  749.     }
  750.     if (userName == "") {
  751.         var email = pageData.identity.email.value;
  752.         userName = getUsernameFromEmail(email); 
  753.     }
  754.     return userName;
  755. }
  756.  
  757. function getCurrentServerType(pageData) {
  758.     var servertype = "pop3";    // hopefully don't resort to default!
  759.     if (serverIsNntp(pageData))
  760.         servertype = "nntp";
  761.     else if (pageData.server && pageData.server.servertype)
  762.         servertype = pageData.server.servertype.value;
  763.     return servertype;
  764. }
  765.  
  766. function getCurrentHostname(pageData) {
  767.     if (serverIsNntp(pageData))
  768.         return pageData.newsserver.hostname.value;
  769.     else
  770.         return pageData.server.hostname.value;
  771. }
  772.  
  773. function UpdateWizardMap() {
  774.     updateMap(GetPageData(), gWizardMap);
  775. }
  776.  
  777. // updates the map based on various odd states
  778. // conditions handled right now:
  779. // - 
  780. function updateMap(pageData, wizardMap) {
  781.     dump("Updating wizard map..\n");
  782.     if (pageData.accounttype) {
  783.         var ismailaccount = pageData.accounttype.mailaccount;
  784.         dump("Accounttype is mail: " + (ismailaccount && ismailaccount.value) + "\n");
  785.         // set up default account stuff
  786.         wizardMap.identity.next = "server";
  787.         wizardMap.done.previous = "accname";
  788.         
  789.         if (pageData.accounttype.mailaccount &&
  790.             pageData.accounttype.mailaccount.value) {
  791.  
  792.             wizardMap.accname.previous = "login";
  793.             
  794.             if (gCurrentAccountData && gCurrentAccountData.wizardSkipPanels) {
  795.                 wizardMap.identity.next = "done";
  796.                 wizardMap.done.previous = "identity";
  797.             }
  798.         }
  799.  
  800.         else if (pageData.accounttype.newsaccount &&
  801.                  pageData.accounttype.newsaccount.value) {
  802.             wizardMap.identity.next = "newsserver";
  803.             wizardMap.accname.previous = "newsserver";
  804.         }
  805.         else {
  806.             dump("Handle other types (" + pageData.accounttype + ") here?\n");
  807.         }
  808.     }
  809.  
  810. }
  811.  
  812. function GetPageData()
  813. {
  814.     return parent.wizardManager.WSM.PageData;
  815. }
  816.     
  817.  
  818. function PrefillAccountForIsp(ispName)
  819. {
  820.     dump("AccountWizard.prefillAccountForIsp(" + ispName + ")\n");
  821.  
  822.     var ispData = getIspDefaultsForUri(ispName);
  823.     
  824.     var pageData = GetPageData();
  825.  
  826.  
  827.     // prefill the rest of the wizard
  828.     dump("PrefillAccountForISP: filling with " + ispData + "\n");
  829.     SetCurrentAccountData(ispData);
  830.     AccountDataToPageData(ispData, pageData);
  831. }
  832.  
  833. // does any cleanup work for the the account data
  834. // - sets the username from the email address if it's not already set
  835. // - anything else?
  836. function FixupAccountDataForIsp(accountData)
  837. {
  838.     var email = accountData.identity.email;
  839.     var username;
  840.  
  841.     if (email) {
  842.         username = getUsernameFromEmail(email);
  843.     }
  844.     
  845.     // fix up the username
  846.     if (!accountData.incomingServer.username) {
  847.         accountData.incomingServer.username = username;
  848.     }
  849.  
  850.     if (!accountData.smtp.username &&
  851.         accountData.smtpRequiresUsername) {
  852.         accountData.smtp.username = username;
  853.     }
  854. }
  855.  
  856. function SetCurrentAccountData(accountData)
  857. {
  858.     //    dump("Setting current account data (" + gCurrentAccountData + ") to " + accountData + "\n");
  859.     gCurrentAccountData = accountData;
  860. }
  861.  
  862. function getInterfaceForType(type) {
  863.     try {
  864.         var protocolInfoContractIDPrefix = "@mozilla.org/messenger/protocol/info;1?type=";
  865.         
  866.         var thisContractID = protocolInfoContractIDPrefix + type;
  867.         
  868.         var protoInfo = Components.classes[thisContractID].getService(Components.interfaces.nsIMsgProtocolInfo);
  869.         
  870.         return protoInfo.serverIID;
  871.     } catch (ex) {
  872.         dump("could not get IID for " + type + ": " + ex + "\n");
  873.         return undefined;
  874.     }
  875. }
  876.  
  877. // flush the XUL cache - just for debugging purposes - not called
  878. function onFlush() {
  879.         var prefs = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
  880.         prefs.SetBoolPref("nglayout.debug.disable_xul_cache", true);
  881.         prefs.SetBoolPref("nglayout.debug.disable_xul_cache", false);
  882.  
  883. }
  884.  
  885. /** If there are no default accounts..
  886.   * this is will be the new default, so enable
  887.   * check for mail at startup
  888.   */
  889. function EnableCheckMailAtStartUpIfNeeded(newAccount)
  890. {
  891.     // Check if default account exists and if that account is alllowed to be
  892.     // a default account. If no such account, make this one as the default account 
  893.     // and turn on the new mail check at startup for the current account   
  894.     if (!(gDefaultAccount && gDefaultAccount.incomingServer.canBeDefaultServer)) { 
  895.         accountm.defaultAccount = newAccount;
  896.         newAccount.incomingServer.loginAtStartUp = true;
  897.     }
  898. }
  899.  
  900. function SetSmtpRequiresUsernameAttribute(accountData) 
  901. {
  902.     // If this is the default server, time to set the smtp user name
  903.     // Set the generic attribute for requiring user name for smtp to true.
  904.     // ISPs can override the pref via rdf files.
  905.     if (!(gDefaultAccount && gDefaultAccount.incomingServer.canBeDefaultServer)) { 
  906.         accountData.smtpRequiresUsername = true;
  907.     }
  908. }
  909.