<commit_before>define([
    "backbone", 
    "authentication/Authentication", 
    "corpus/Corpus",
    "data_list/DataList",
    "datum/DatumFields",
    "search/Search",
    "datum/Session",
    "app/AppRouter",
    "confidentiality_encryption/Confidential",
    "user/User",
    "user/UserMask",
    "libs/Utils"
], function(
    Backbone, 
    Authentication, 
    Corpus,
    DataList,
    DatumFields,
    Search,
    Session,
    AppRouter,
    Confidential,
    User,
    UserMask
) {
  var App = Backbone.Model.extend(
  /** @lends App.prototype */
  {
    /**
     * @class The App handles the reinitialization and loading of the app
     *        depending on which platform (Android, Chrome, web) the app is
     *        running, who is logged in etc.
     * 
     * The App should be serializable to save state to local storage for the
     * next run.
     * 
     * @property {Authentication} authentication The auth member variable is an
     *           Authentication object permits access to the login and logout
     *           functions, and the database of users depending on whether the
     *           app is online or not.
     * 
     * @property {Corpus} corpus The corpus is a Corpus object which will permit
     *           access to the datum, and the data lists. The corpus feeds the
     *           search object with indexes and fields for advanced search, the
     *           corpus has datalists, has teams with permissions, has a
     *           confidentiality_encryption key, it's datum have sessions, its
     *           datalists have export.
     * 
     * @property {Search} search The search is the primary surface where the
     *           global search features will attach.
     * 
     * @property {Session} currentSession The session that is currently open.
     * 
     * @extends Backbone.Model
     * @constructs
     */
    initialize : function() {
      this.bind('error', function(model, error) {
        Utils.debug("Error in App: " + error);
      });
      
    },
    
    defaults : {
      corpus : Corpus,
      authentication : new Authentication(),
      currentSession : Session,
      currentDataList : DataList
    },
    
    // Internal models: used by the parse function
    model : {
      corpus : Corpus,
      authentication : Authentication,
      currentSession : Session,
      currentDataList : DataList
    },
    
    /**
     * This function creates the backbone objects, and links them up so that
     * they are ready to be used in the views. This function should be called on
     * app load, either by main, or by welcome new user. This function should
     * not be called at any later time as it will break the connection between
     * the views and the models. To load different models into the app after it
     * has first loaded, use the loadBackboneObjectsById function below.
     * 
     * @param callback
     */
    createAppBackboneObjects : function(optionalcorpusname, callback){
      if(optionalcorpusname == null){
        optionalcorpusname == "";
      }
      if (this.get("authentication").get("userPublic") == undefined) {
        var u = new UserMask({corpusname: optionalcorpusname});
        this.get("authentication").set("userPublic", u);
      }
      if (this.get("authentication").get("userPrivate") == undefined) {
        var u2 = new User();
        this.get("authentication").set("userPrivate", u2);
      }
      var c = new Corpus({corpusname : optionalcorpusname});
      this.set("corpus", c);

      var s = new Session({
        corpusname : optionalcorpusname,
        sessionFields : c.get("sessionFields").clone()
      });
      this.set("currentSession", s);

      var dl = new DataList({corpusname: optionalcorpusname});
      this.set("currentDataList", dl);
      
      if (typeof callback == "function") {
        callback();
      }
    },
    /**
     * Accepts the ids to load the app. This is a helper function which is caled
     * at the three entry points, main (if there is json in the localstorage
     * from where the user was last working), Welcome new user has a similar
     * function but which creates a user and their recent data, and
     * authentication calls this function to load the users most recent work
     * after they have authenticated (if they were the user who was logged in,
     * they take it frmo local storage, if they were not then the data will have
     * to be synced.)
     * 
     * Preconditions:
     * The user is already authenticated with their corpus server,
     * The corpus server has sent down(replicated) the data.
     * 
     * @param corpusid
     * @param sessionid
     * @param datalistid
     */
    loadBackboneObjectsById : function(couchConnection, appids, callback) {
      if(couchConnection == null || couchConnection == undefined){
        couchConnection = this.get("corpus").get("couchConnection");
      }
      var self = this;
      var c = this.get("corpus");
      c.set({
        "id" : appids.corpusid,
        "corpusname" : couchConnection.corpusname,
        couchConnection : couchConnection
      });
      c.id = appids.corpusid; //tried setting both ids to match, and it worked!!
      
      c.changeCorpus(couchConnection, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        c.fetch({
          success : function(e) {
            Utils.debug("Corpus fetched successfully" + e);
            //show pretty views after loading everything.
            window.appView.renderReadonlyCorpusViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching corpus. Loading defaults..."+e);
          }
        });
      });
      
      var s = this.get("currentSession");
      s.set({"id": appids.sessionid,
        "corpusname" : couchConnection.corpusname});
      s.id = appids.sessionid; //tried setting both ids to match, and it worked!!

      s.changeCorpus(couchConnection.corpusname, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        s.fetch({
          success : function(e) {
            Utils.debug("Session fetched successfully" +e);
            //show pretty views after loading everything.
            window.appView.renderReadonlySessionViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching the session. Loading defaults..."+e);
            s.set(
                "sessionFields", self.get("corpus").get("sessionFields").clone()
            );
          }
        });
      });
      var dl = this.get("currentDataList");
      dl.set({
        "id" : appids.datalistid, 
        "corpusname" : couchConnection.corpusname});
      dl.id = appids.datalistid; //tried setting both ids to match, and it worked!!

      dl.changeCorpus(couchConnection.corpusname, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        dl.fetch({
          success : function(e) {
            Utils.debug("Data list fetched successfully" +e);
            //show pretty views after loading everything.
            window.appView.renderReadonlyDataListViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching the data list. Loading defaults..."+e);
          }
        });
      });
      
      //TODO move this callback after the fetch succeeds?
      if (typeof callback == "function") {
        callback();
        //show pretty views after loading everything.
      }
      
    },
    router : AppRouter,
    
    /**
     * This function should be called before the user leaves the page, it should also be called before the user clicks sync
     * It helps to maintain where the user was, what corpus they were working on etc. It creates the json that is used to reload<commit_msg>working on why the session stays in edit view after loading an existing user who is not sapir<commit_after>define([
    "backbone", 
    "authentication/Authentication", 
    "corpus/Corpus",
    "data_list/DataList",
    "datum/DatumFields",
    "search/Search",
    "datum/Session",
    "app/AppRouter",
    "confidentiality_encryption/Confidential",
    "user/User",
    "user/UserMask",
    "libs/Utils"
], function(
    Backbone, 
    Authentication, 
    Corpus,
    DataList,
    DatumFields,
    Search,
    Session,
    AppRouter,
    Confidential,
    User,
    UserMask
) {
  var App = Backbone.Model.extend(
  /** @lends App.prototype */
  {
    /**
     * @class The App handles the reinitialization and loading of the app
     *        depending on which platform (Android, Chrome, web) the app is
     *        running, who is logged in etc.
     * 
     * The App should be serializable to save state to local storage for the
     * next run.
     * 
     * @property {Authentication} authentication The auth member variable is an
     *           Authentication object permits access to the login and logout
     *           functions, and the database of users depending on whether the
     *           app is online or not.
     * 
     * @property {Corpus} corpus The corpus is a Corpus object which will permit
     *           access to the datum, and the data lists. The corpus feeds the
     *           search object with indexes and fields for advanced search, the
     *           corpus has datalists, has teams with permissions, has a
     *           confidentiality_encryption key, it's datum have sessions, its
     *           datalists have export.
     * 
     * @property {Search} search The search is the primary surface where the
     *           global search features will attach.
     * 
     * @property {Session} currentSession The session that is currently open.
     * 
     * @extends Backbone.Model
     * @constructs
     */
    initialize : function() {
      this.bind('error', function(model, error) {
        Utils.debug("Error in App: " + error);
      });
      
    },
    
    defaults : {
      corpus : Corpus,
      authentication : new Authentication(),
      currentSession : Session,
      currentDataList : DataList
    },
    
    // Internal models: used by the parse function
    model : {
      corpus : Corpus,
      authentication : Authentication,
      currentSession : Session,
      currentDataList : DataList
    },
    
    /**
     * This function creates the backbone objects, and links them up so that
     * they are ready to be used in the views. This function should be called on
     * app load, either by main, or by welcome new user. This function should
     * not be called at any later time as it will break the connection between
     * the views and the models. To load different models into the app after it
     * has first loaded, use the loadBackboneObjectsById function below.
     * 
     * @param callback
     */
    createAppBackboneObjects : function(optionalcorpusname, callback){
      if(optionalcorpusname == null){
        optionalcorpusname == "";
      }
      if (this.get("authentication").get("userPublic") == undefined) {
        var u = new UserMask({corpusname: optionalcorpusname});
        this.get("authentication").set("userPublic", u);
      }
      if (this.get("authentication").get("userPrivate") == undefined) {
        var u2 = new User();
        this.get("authentication").set("userPrivate", u2);
      }
      var c = new Corpus({corpusname : optionalcorpusname});
      this.set("corpus", c);

      var s = new Session({
        corpusname : optionalcorpusname,
        sessionFields : c.get("sessionFields").clone()
      });
      this.set("currentSession", s);

      var dl = new DataList({corpusname: optionalcorpusname});
      this.set("currentDataList", dl);
      
      if (typeof callback == "function") {
        callback();
      }
    },
    /**
     * Accepts the ids to load the app. This is a helper function which is caled
     * at the three entry points, main (if there is json in the localstorage
     * from where the user was last working), Welcome new user has a similar
     * function but which creates a user and their recent data, and
     * authentication calls this function to load the users most recent work
     * after they have authenticated (if they were the user who was logged in,
     * they take it frmo local storage, if they were not then the data will have
     * to be synced.)
     * 
     * Preconditions:
     * The user is already authenticated with their corpus server,
     * The corpus server has sent down(replicated) the data.
     * 
     * @param corpusid
     * @param sessionid
     * @param datalistid
     */
    loadBackboneObjectsById : function(couchConnection, appids, callback) {
      if(couchConnection == null || couchConnection == undefined){
        couchConnection = this.get("corpus").get("couchConnection");
      }
      var self = this;
      var c = this.get("corpus");
      c.set({
        "corpusname" : couchConnection.corpusname,
        couchConnection : couchConnection
      });
      c.id = appids.corpusid; //tried setting both ids to match, and it worked!!
      
      c.changeCorpus(couchConnection, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        c.fetch({
          success : function(e) {
            Utils.debug("Corpus fetched successfully" + e);
            //show pretty views after loading everything.
            window.appView.renderReadonlyCorpusViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching corpus. Loading defaults..."+e);
          }
        });
      });
      
      var s = this.get("currentSession");
      s.set({
        "corpusname" : couchConnection.corpusname});
      s.id = appids.sessionid; //tried setting both ids to match, and it worked!!

      s.changeCorpus(couchConnection.corpusname, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        s.fetch({
          success : function(e) {
            Utils.debug("Session fetched successfully" +e);
            //show pretty views after loading everything.
            window.appView.renderReadonlySessionViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching the session. Loading defaults..."+e);
            s.set(
                "sessionFields", self.get("corpus").get("sessionFields").clone()
            );
          }
        });
      });
      var dl = this.get("currentDataList");
      dl.set({
        "corpusname" : couchConnection.corpusname});
      dl.id = appids.datalistid; //tried setting both ids to match, and it worked!!

      dl.changeCorpus(couchConnection.corpusname, function(){
        //fetch only after having setting the right pouch which is what changeCorpus does.
        dl.fetch({
          success : function(e) {
            Utils.debug("Data list fetched successfully" +e);
            //show pretty views after loading everything.
            window.appView.renderReadonlyDataListViews();
          },
          error : function(e) {
            Utils.debug("There was an error fetching the data list. Loading defaults..."+e);
          }
        });
      });
      
      //TODO move this callback after the fetch succeeds?
      if (typeof callback == "function") {
        callback();
        //show pretty views after loading everything.
      }
      
    },
    router : AppRouter,
    
    /**
     * This function should be called before the user leaves the page, it should also be called before the user clicks sync
     * It helps to maintain where the user was, what corpus they were working on etc. It creates the json that is used to reload
{'fraction_non_alphanumeric': 0.09358828726492491, 'fraction_numerical': 0.0002524296352391771, 'mean_word_length': 2.228152373192096, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2082417', 'n_tokens_mistral': 4222, 'n_tokens_neox': 4130, 'n_words': 1475}