<commit_before>// Mobile Router
// =============

/* global _ */
// Includes file dependencies
define([
	"jquery",
	"parse",
    "pretty",
    "jscookie",
    "moment",
	"../models/CategoryModel",
	"../collections/CategoriesCollection",
	"../views/CategoryView",
    "../views/CharactersListView",
    "../models/Vampire",
    "../models/Werewolf",
    "../collections/Vampires",
    "../views/CharacterView",
    "../views/SimpleTraitCategoryView",
    "../views/SimpleTraitNewView",
    "../models/SimpleTrait",
    "../views/SimpleTraitChangeView",
    "../models/VampireCreation",
    "../views/CharacterCreateView",
    "../views/CharacterNewView",
    "../views/CharacterPrintView",
    "../views/CharacterCostsView",
    "../views/SimpleTextNewView",
    "../views/SimpleTraitSpecializationView",
    "../views/CharacterLogView",
    "../views/CharacterHistoryView",
    "../views/SignupView",
    "../views/LoginView",
    "../views/CharacterExperienceView",
    "../views/UserSettingsProfileView",
    "../views/CharacterPortraitView",
    "../views/TroupeCharacterRelationshipsNetworkView",
    "../views/CharacterDeleteView",
    "../views/PlayerOptionsView",
    "../views/TroupeNewView",
    "../views/TroupesListView",
    "../views/TroupeView",
    "../views/UsersView",
    "../views/TroupeEditStaffView",
    "../models/Troupe",
    "../helpers/PromiseFailReport",
    "../views/TroupePortraitView",
    "text!../templates/footer.html",
    "../views/AdministrationUserView",
    "../views/PasswordReset",
    "../views/CharacterApprovalView",
    "../helpers/InjectAuthData",
    //"../views/AdministrationUserPatronagesView",
    "../views/AdministrationUserView",
    "../collections/Patronages",
    "../views/PatronagesView",
    "../views/PatronageView",
    "../collections/Users",
    "../models/Patronage",
    "../helpers/UserWreqr",
    "../views/CharactersSummarizeListView",
    "../views/CharacterRenameView",
    "../views/SimpleTraitNewSpecializationView",
    "../views/CharacterCreateSimpleTraitNewView",
    "../views/DescriptionsView",
    "../models/Werewolf",
    "../views/CharactersPrintView",
    "../views/CharactersSelectToPrintView",
    "../views/CharacterLongTextView"
], function ($,
             Parse,
             pretty,
             Cookie,
             moment,
             CategoryModel,
             CategoriesCollection,
             CategoryView,
             CharactersListView,
             Vampire,
             Werewolf,
             Vampires,
             CharacterView,
             SimpleTraitCategoryView,
             SimpleTraitNewView,
             SimpleTrait,
             SimpleTraitChangeView,
             VampireCreation,
             CharacterCreateView,
             CharacterNewView,
             CharacterPrintView,
             CharacterCostsView,
             SimpleTextNewView,
             SimpleTraitSpecializationView,
             CharacterLogView,
             CharacterHistoryView,
             SignupView,
             LoginView,
             CharacterExperienceView,
             UserSettingsProfileView,
             CharacterPortraitView,
             TroupeCharacterRelationshipsNetworkView,
             CharacterDeleteView,
             PlayerOptionsView,
             TroupeNewView,
             TroupesListView,
             TroupeView,
             UsersView,
             TroupeEditStaffView,
             Troupe,
             PromiseFailReport,
             TroupePortraitView,
             footer_html,
             AdministrationUserView,
             PasswordResetView,
             CharacterApprovalView,
             InjectAuthData,
             AdministrationUserPatronagesView,
             Patronages,
             PatronagesView,
             PatronageView,
             Users,
             Patronage,
             UserChannel,
             CharactersSummarizeListView,
             CharacterRenameView,
             SimpleTraitNewSpecializationView,
             CharacterCreateSimpleTraitNewView,
             DescriptionsView,
             Werewolf,
             CharactersPrintView,
             CharactersSelectToPrintView,
             CharacterLongTextView
) {

    // Extends Backbone.Router
    var CategoryRouter = Parse.Router.extend( {

        // The Router constructor
        initialize: function() {

            this._character = null;

            _.bindAll(this, "get_character");

            // Instantiates a new Animal Category View
            this.animalsView = new CategoryView( { el: "#animals", collection: new CategoriesCollection( [] , { type: "animals" } ) } );

            // Instantiates a new Colors Category View
            this.colorsView = new CategoryView( { el: "#colors", collection: new CategoriesCollection( [] , { type: "colors" } ) } );

            // Instantiates a new Vehicles Category View
            this.vehiclesView = new CategoryView( { el: "#vehicles", collection: new CategoriesCollection( [] , { type: "vehicles" } ) } );

            this.characters = new CharactersListView( {el: "#characters-all", collection: new Vampires});
            this.troupeCharacters = new CharactersListView({el: "#troupe-characters-all", collection: new Vampires});

            this.character = new CharacterView({ el: "#character"});

            this.simpleTraitCategoryView = new SimpleTraitCategoryView({el: "#simpletraitcategory-all"});
            this.simpleTraitNewView = new SimpleTraitNewView({el: "#simpletrait-new > div[role='main']"});
            this.simpleTraitChangeView = new SimpleTraitChangeView({el: "#simpletrait-change"});
            this.simpleTextNewView = new SimpleTextNewView({el: "#simpletext-new"});
            this.simpleTraitSpecializationView = new SimpleTraitSpecializationView({el: "#simpletrait-specialization"});
            this.simpleTraitNewSpecializationView = new SimpleTraitNewSpecializationView({el: "#simpletrait-new-specialization"});
            this.characterCreateSimpleTraitNewView = new CharacterCreateSimpleTraitNewView({el: "#character-create-simpletrait-new"});

            this.characterCreateView = new CharacterCreateView({el: "#character-create"});
            this.characterNewView = new CharacterNewView({el: "#character-new-form"});

            this.characterPrintView = new CharacterPrintView({el: "#printable-sheet"});
            this.characterCostsView = new CharacterCostsView({el: "#character-costs"});
            this.characterLogView = new CharacterLogView({el: "#character-log"});
            this.characterHistoryView = new CharacterHistoryView({el: "#character-history"});
            this.characterExperienceView = new CharacterExperienceView({el: "#experience-notations-all"});
            this.characterPortraitView = new CharacterPortraitView({el: "#character-portrait"});
            this.characterDeleteView = new CharacterDeleteView({el: "#character-delete"});
            this.characterApprovalView = new CharacterApprovalView({el: "#character-approval > div[role='main']"});

            this.loginView = new LoginView();
            this.signupView = new SignupView();

            this.troupeCharacterRelationshipsNetworkView = new TroupeCharacterRelationshipsNetworkView({el: "#troupe-character-relationships-network"});

            /*
            if (!Parse.User.current()) {
                Parse.User.logIn("devuser", "thedumbness");
            }
            */

            // Tells Backbone to start watching for hashchange events
            Parse.history.start();
        },

        // Backbone.js Routes
        routes: {

            // When there is no hash bang on the url, the home method is called
            "": "home",
            "start": "home",
            
            "about": "about",

            "logout": "logout",
            "signup": "signup",
            "reset": "<PASSWORD>",

            "profile": "profile",

            // When #category? is on the url, the category method is called
            "category?:type": "category",

            "victims?:type": "victims",

            "characters?:type": "characters",

            "character?:id": "character",

            "simpletraits/:category/:cid/:type": "simpletraits",

            "simpletrait/:category/:cid/:bid": "simpletrait",
            "simpletrait/specialize/:category/:cid/:bid": "simpletraitspecialize",
            "simpletrait/spacer/:category/:cid/:name/:value/:free_value/new": "simpletraitnew",
            "simpletrait/specialize/:category/:cid/:name/:value/:free_value/new": "simpletrait_new_specialize",
            
            "simpletext/:category/:target/:cid/pick":   "simpletextpick",
            "simpletext/:category/:target/:cid/unpick":   "simpletextunpick",

            "charactercreate/:cid": "charactercreate",

            "charactercreate/simpletraits/:category/:cid/pick/:i": "charactercreatepicksimpletrait",
            "charactercreate/simpletraits/:category/:cid/unpick/:stid/:i": "charactercreateunpicksimpletrait",
            "charactercreate/simpletraits/:category/:cid/specialize/:stid/:i": "charactercreatespecializesimpletrait",
            "charactercreate/simpletext/:category/:target/:cid/pick": "charactercreatepicksimpletext",
            "charactercreate/simpletext/:category/:target/:cid/unpick": "charactercreateunpicksimpletext",
            "charactercreate/complete/:cid": "charactercreatecomplete",

            "characternew": "characternew",

            "character/:cid/print": "characterprint",
            "character/:cid/costs": "charactercosts",
            "character/:cid/log/:start/:changeBy": "characterlog",
            "character/:cid/history/:id": "characterhistory",
            "character/:cid/portrait": "characterportrait",
            "character/:cid/delete": "characterdelete",
            "character/:cid/troupes": "character_list_troupes",
            "character/:cid/troupes/leave": "character_pick_troupe_to_leave",
            "character/:cid/troupes/join": "character_pick_troupe_to_join",
            "character/:cid/troupe/:tid/join": "character_join_troupe",
            "character/:cid/troupe/:tid/leave": "character_leave_troupe",
            "character/:cid/troupe/:tid/show": "character_show_troupe",
            "character/:cid/approval": "characterapproval",
            "character/:cid/rename": "characterrename",
            "character/:cid/approved": "character_show_approved",
            "character/:cid/extendedprinttext": "character_extended_print_text",
            "character/:cid/backgroundlt": "character_background_long_text",
            "character/:cid/noteslt": "character_notes_long_text",

            "character/:cid/experience/:start/:changeBy": "characterexperience",

            "troupe/new": "troupenew",
            "troupes": "troupes",
            "troupe/:id": "troupe",
            "troupe/:id/staff/add": "troupeaddstaff",
            "troupe/:id/staff/edit/:uid": "troupeeditstaff",
            "troupe/:id/characters/:type": "troupecharacters",
            "troupe/:id/characters/summarize/:type": "troupesummarizecharacters",
            "troupe/:id/characters/selecttoprint/:type": "troupe_select_to_print_characters",
            "troupe/:id/characters/print/:type": "troupe_print_characters",
            "troupe/:id/characters/relationships/network": "troupe_relationship_network",
            "troupe/:id/character/:cid": "troupe_character",
            "troupe/:id/portrait": "troupe_portrait",

            "administration": "administration",
            "administration/characters/all": "administration_characters_all",
            "administration/characters/summarize": "administration_characters_summarize",
            "administration/character/:id": "administration_character",
            "administration/users/all": "administration_users",
            "administration/user/:id": "administration_user",
            "administration/patronages/user/:id": "administration_user_patronages",
            "administration/patronages": "administration_patronages",
            "administration/patronage/:id": "administration_patronage",
            "administration/patronages/new": "administration_patronage_new",
            "administration/patronages/new/:userid": "administration_patronage_new",
            "administration/descriptions": "administration_descriptions",

        },

        // Home method
        home: function() {
            var self = this;
            this.enforce_logged_in().then(function () {
                var q = (new Parse.Query(Parse.Role)).equalTo("users", Parse.User.current());
                return q.count();
            }).then(function (count) {
                var user = Parse.User.current();
                if (0 < count) {
                    user.set("storytellerinterface", true);
                } else {
                    user.set("storytellerinterface", false);
                }
                InjectAuthData(user);
                return user.save();
            }).then(function () {
                self.playerOptionsView = self.playerOptionsView || new PlayerOptionsView({el: "#player-options"}).render();
                $.mobile.changePage("#player-options", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },

        logout: function() {
            Parse.User.logOut().always(function () {
                return hello('facebook').logout();
            }).always(function() {
                window.location.hash = "";
                window.location.reload();
            });
        },

        signup: function() {
            if (!Parse.User.current()) {
                // Programatically changes to the categories page
                $.mobile.changePage("#signup", {reverse: false, changeHash: false});
            } else {
                window.location.hash = "";
            }
        },
        
        about: function() {
            $.mobile.changePage("#about", {reverse: false, changeHash: false})
        },

        resetpassword: function() {
            var self = this;
            self.resetPasswordView = self.resetPasswordView || new PasswordResetView({el: "#user-reset-password"});
            self.resetPasswordView.render();
            $.mobile.changePage("#user-reset-password", {reverse: false, changeHash: false});
        },

        profile: function() {
            var self = this;
            self.enforce_logged_in().then(function() {
                return UserChannel.get_users();
            }).then(function() {
                self.set_back_button("#");
                self.userSettingsProfileView = self.userSettingsProfileView || new UserSettingsProfileView().setup();
                $.mobile.changePage("#user-settings-profile", {reverse: false, changeHash: false});
            })
        },

        set_back_button: function(url) {
            $("#header-back-button").attr("href", url);
        },


        charactercosts: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, ["skills", "disciplines", "backgrounds"]).done(function (character) {
                self.characterCostsView.model = character;
                self.characterCostsView.render();
                $.mobile.changePage("#character-costs", {reverse: false, changeHash: false});
            });
        },

        characterlog: function(cid, start, changeBy) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").done(function (character) {
                self.characterLogView.register(character, start, changeBy);
                var activePage = $(".ui-page-active").attr("id");
                var r = $.mobile.changePage("#character-log", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            });
        },

        characterexperience: function(cid, start, changeBy) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").done(function (character) {
                self.characterExperienceView.register(character, start, changeBy);
                var activePage = $(".ui-page-active").attr("id");
                var r = $.mobile.changePage("#experience-notations-all", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            });
        },

        characterhistory: function(cid, id) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterHistoryView.register(character, id).then(function () {
                    var activePage = $(".ui-page-active").attr("id");
                    var r = $.mobile.changePage("#character-history", {reverse: false, changeHash: false});
                    $.mobile.loading("hide");
                });
            }).fail(PromiseFailReport);
        },

        characterapproval: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterApprovalView.register(character).then(function () {
                    var activePage = $(".ui-page-active").attr("id");
                    var r = $.mobile.changePage("#character-approval", {reverse: false, changeHash: false});
                    $.mobile.loading("hide");
                });
            }).fail(PromiseFailReport);
        },

        character_show_approved: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.get_transformed_last_approved();
            }).then(function (transformed) {
                if (null == transformed) {
                    $.mobile.changePage("#character-print-no-approval", {reverse: false, changeHash: false});
                } else {
                    transformed.transform_description = [];
                    self.characterPrintView.setup(transformed);
                    $.mobile.changePage("#printable-sheet", {reverse: false, changeHash: false});
                }
            }).fail(PromiseFailReport);
        },

        characterrename: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterRenameView = self.characterRenameView || new CharacterRenameView({el: "#character-rename-main"});
                return self.characterRenameView.register(character);
            }).then(function () {
                $.mobile.changePage("#character-rename", {reverse: false, changeHash: false});
            }).always(function () {
                $.mobile.loading("hide");
            }).fail(PromiseFailReport);
        },

        characterprint: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("extended_print_text");
            }).then(function (character) {
                character.transform_description = [];
                self.characterPrintView.setup(character);
                $.mobile.changePage("#printable-sheet", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },

        characternew: function() {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#characters?all");
            self.characterNewView.render();
            $.mobile.changePage("#character-new", {reverse: false, changeHash: false});
        },

        charactercreate: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, []).then(function (character) {
                return character.fetch_all_creation_elements();
            }).done(function (character) {
                self.characterCreateView.model = character;
                self.characterCreateView.render();
                self.characterCreateView.scroll_back_after_page_change();
                $.mobile.changePage("#character-create", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            }).fail(PromiseFailReport);
        },

        charactercreatepicksimpletrait: function(category, cid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).done(function (c) {
                var specialCategory;
                if ("disciplines" == category) {
                    specialCategory = "in clan disciplines";
                } else if ("wta_gifts" == category) {
                    specialCategory = ["affinity", "show_only_value_1"];
                }
                self.characterCreateSimpleTraitNewView.register(
                    c,
                    category,
                    i,
                    "#charactercreate/<%= self.character.id %>",
                    specialCategory,
                    "#charactercreate/simpletraits/<%= self.category %>/<%= self.character.id %>/specialize/<%= b.linkId() %>/" + i);
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                $.mobile.changePage("#character-create-simpletrait-new", {reverse: false, changeHash: false});
            });
        },


        charactercreatespecializesimpletrait: function(category, cid, stid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                return character.get_trait(category, stid);
            }).then(function (trait, character) {
                return self.simpleTraitSpecializationView.register(
                    character,
                    trait,
                    category,
                    window.location.hash,
                    "#charactercreate/" + character.id
                );
            }).then(function () {
                $.mobile.changePage("#simpletrait-specialization", {reverse: false, changeHash: false});
            }).fail(function(error) {
                console.log(error.message);
            });
        },

        charactercreateunpicksimpletrait: function(category, cid, stid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                return character.unpick_from_creation(category, stid, i);
            }).done(function (c) {
                window.location.hash = "#charactercreate/" + c.id;
            }).fail(function(error) {
                console.log(error.message);
            });
        },

        charactercreatepicksimpletext: function(category, target, cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).done(function (c) {
                self.simpleTextNewView.register(c, category, target, "#charactercreate/" + c.id);
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                $.mobile.changePage("#simpletext-new", {reverse: false, changeHash: false});
            });
        },
        
        charactercreateunpicksimpletext: function(category, target, cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                self.character.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                return character.unpick_text(target);
            }).then(function (c) {
                window.location.hash = "#charactercreate/" + c.id;
            }).fail(PromiseFailReport);
        },
        
        charactercreatecomplete: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid).done(function (c) {
                return c.complete_character_creation();
            }).then(function () {
                window.location.hash = "#character?" + cid;
            }).fail(function (error) {
                alert(error.message);
                window.location.hash = "#charactercreate/" + cid;
            }).fail(PromiseFailReport);
        },

        characterportrait: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid).done(function (c) {
                return self.characterPortraitView.register(c);
            }).always(function() {
                $.mobile.changePage("#character-portrait", {reverse: false, changeHash: false});
            });
        },
        
        character_extended_print_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("extended_print_text");
            }).then(function (character) {
                character.transform_description = [];
                self.cept = self.cept || new CharacterLongTextView({
                    el: "#extended-print-text",
                });
                self.cept.setup(
                    character,
                    {
                        category: "extended_print_text",
                        pretty: "Extended Print Text",
                        description: "Additional text to display with your printed character sheet.",                       
                    });
                $.mobile.changePage("#extended-print-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },
        
        character_background_long_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("background");
            }).then(function (character) {
                character.transform_description = [];
                self.clt = self.clt || new CharacterLongTextView({
                    el: "#long-text",
                });
                self.clt.setup(
                    character,
                    {
                        category: "background",
                        pretty: "Background",
                        description: "History and backstory for your character.",                       
                    });
                $.mobile.changePage("#long-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },
        
        character_notes_long_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("notes");
            }).then(function (character) {
                character.transform_description = [];
                self.clt = self.clt || new CharacterLongTextView({
                    el: "#long-text",
                });
                self.clt.setup(
                    character,
                    {
                        category: "notes",
                        pretty: "Notes",
                        description: "Notes about your character's interactions and progression", 
                    });
                $.mobile.changePage("#long-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },
        
        show_character_helper: function(id, back_url) {
            $.mobile.loading("show");
            this.set_back_button(back_url);
            var c = this.character;
            this.get_character(id).done(function (m) {
                c.model = m;
                c.render();
                c.scroll_back_after_page_change();
                $.mobile.changePage("#character", {reverse: false, changeHash:false});
            }).then(function () {
                $.mobile.loading("hide");
            }).fail(PromiseFailReport).fail(function () {
                window.location.hash = back_url;
            });
        },

        character: function(id) {
            this.show_character_helper(id, "#characters?all");
        },

        troupe_character: function(id, cid) {
            this.show_character_helper(cid, "#troupe/" + id + "/characters/all");
        },

        administration_character: function(id) {
            this.show_character_helper(id, "#administration/characters/all");
        },

        administration_users: function() {<commit_msg>Prevent stuck loading bar on background and notes<commit_after>// Mobile Router
// =============

/* global _ */
// Includes file dependencies
define([
	"jquery",
	"parse",
    "pretty",
    "jscookie",
    "moment",
	"../models/CategoryModel",
	"../collections/CategoriesCollection",
	"../views/CategoryView",
    "../views/CharactersListView",
    "../models/Vampire",
    "../models/Werewolf",
    "../collections/Vampires",
    "../views/CharacterView",
    "../views/SimpleTraitCategoryView",
    "../views/SimpleTraitNewView",
    "../models/SimpleTrait",
    "../views/SimpleTraitChangeView",
    "../models/VampireCreation",
    "../views/CharacterCreateView",
    "../views/CharacterNewView",
    "../views/CharacterPrintView",
    "../views/CharacterCostsView",
    "../views/SimpleTextNewView",
    "../views/SimpleTraitSpecializationView",
    "../views/CharacterLogView",
    "../views/CharacterHistoryView",
    "../views/SignupView",
    "../views/LoginView",
    "../views/CharacterExperienceView",
    "../views/UserSettingsProfileView",
    "../views/CharacterPortraitView",
    "../views/TroupeCharacterRelationshipsNetworkView",
    "../views/CharacterDeleteView",
    "../views/PlayerOptionsView",
    "../views/TroupeNewView",
    "../views/TroupesListView",
    "../views/TroupeView",
    "../views/UsersView",
    "../views/TroupeEditStaffView",
    "../models/Troupe",
    "../helpers/PromiseFailReport",
    "../views/TroupePortraitView",
    "text!../templates/footer.html",
    "../views/AdministrationUserView",
    "../views/PasswordReset",
    "../views/CharacterApprovalView",
    "../helpers/InjectAuthData",
    //"../views/AdministrationUserPatronagesView",
    "../views/AdministrationUserView",
    "../collections/Patronages",
    "../views/PatronagesView",
    "../views/PatronageView",
    "../collections/Users",
    "../models/Patronage",
    "../helpers/UserWreqr",
    "../views/CharactersSummarizeListView",
    "../views/CharacterRenameView",
    "../views/SimpleTraitNewSpecializationView",
    "../views/CharacterCreateSimpleTraitNewView",
    "../views/DescriptionsView",
    "../models/Werewolf",
    "../views/CharactersPrintView",
    "../views/CharactersSelectToPrintView",
    "../views/CharacterLongTextView"
], function ($,
             Parse,
             pretty,
             Cookie,
             moment,
             CategoryModel,
             CategoriesCollection,
             CategoryView,
             CharactersListView,
             Vampire,
             Werewolf,
             Vampires,
             CharacterView,
             SimpleTraitCategoryView,
             SimpleTraitNewView,
             SimpleTrait,
             SimpleTraitChangeView,
             VampireCreation,
             CharacterCreateView,
             CharacterNewView,
             CharacterPrintView,
             CharacterCostsView,
             SimpleTextNewView,
             SimpleTraitSpecializationView,
             CharacterLogView,
             CharacterHistoryView,
             SignupView,
             LoginView,
             CharacterExperienceView,
             UserSettingsProfileView,
             CharacterPortraitView,
             TroupeCharacterRelationshipsNetworkView,
             CharacterDeleteView,
             PlayerOptionsView,
             TroupeNewView,
             TroupesListView,
             TroupeView,
             UsersView,
             TroupeEditStaffView,
             Troupe,
             PromiseFailReport,
             TroupePortraitView,
             footer_html,
             AdministrationUserView,
             PasswordResetView,
             CharacterApprovalView,
             InjectAuthData,
             AdministrationUserPatronagesView,
             Patronages,
             PatronagesView,
             PatronageView,
             Users,
             Patronage,
             UserChannel,
             CharactersSummarizeListView,
             CharacterRenameView,
             SimpleTraitNewSpecializationView,
             CharacterCreateSimpleTraitNewView,
             DescriptionsView,
             Werewolf,
             CharactersPrintView,
             CharactersSelectToPrintView,
             CharacterLongTextView
) {

    // Extends Backbone.Router
    var CategoryRouter = Parse.Router.extend( {

        // The Router constructor
        initialize: function() {

            this._character = null;

            _.bindAll(this, "get_character");

            // Instantiates a new Animal Category View
            this.animalsView = new CategoryView( { el: "#animals", collection: new CategoriesCollection( [] , { type: "animals" } ) } );

            // Instantiates a new Colors Category View
            this.colorsView = new CategoryView( { el: "#colors", collection: new CategoriesCollection( [] , { type: "colors" } ) } );

            // Instantiates a new Vehicles Category View
            this.vehiclesView = new CategoryView( { el: "#vehicles", collection: new CategoriesCollection( [] , { type: "vehicles" } ) } );

            this.characters = new CharactersListView( {el: "#characters-all", collection: new Vampires});
            this.troupeCharacters = new CharactersListView({el: "#troupe-characters-all", collection: new Vampires});

            this.character = new CharacterView({ el: "#character"});

            this.simpleTraitCategoryView = new SimpleTraitCategoryView({el: "#simpletraitcategory-all"});
            this.simpleTraitNewView = new SimpleTraitNewView({el: "#simpletrait-new > div[role='main']"});
            this.simpleTraitChangeView = new SimpleTraitChangeView({el: "#simpletrait-change"});
            this.simpleTextNewView = new SimpleTextNewView({el: "#simpletext-new"});
            this.simpleTraitSpecializationView = new SimpleTraitSpecializationView({el: "#simpletrait-specialization"});
            this.simpleTraitNewSpecializationView = new SimpleTraitNewSpecializationView({el: "#simpletrait-new-specialization"});
            this.characterCreateSimpleTraitNewView = new CharacterCreateSimpleTraitNewView({el: "#character-create-simpletrait-new"});

            this.characterCreateView = new CharacterCreateView({el: "#character-create"});
            this.characterNewView = new CharacterNewView({el: "#character-new-form"});

            this.characterPrintView = new CharacterPrintView({el: "#printable-sheet"});
            this.characterCostsView = new CharacterCostsView({el: "#character-costs"});
            this.characterLogView = new CharacterLogView({el: "#character-log"});
            this.characterHistoryView = new CharacterHistoryView({el: "#character-history"});
            this.characterExperienceView = new CharacterExperienceView({el: "#experience-notations-all"});
            this.characterPortraitView = new CharacterPortraitView({el: "#character-portrait"});
            this.characterDeleteView = new CharacterDeleteView({el: "#character-delete"});
            this.characterApprovalView = new CharacterApprovalView({el: "#character-approval > div[role='main']"});

            this.loginView = new LoginView();
            this.signupView = new SignupView();

            this.troupeCharacterRelationshipsNetworkView = new TroupeCharacterRelationshipsNetworkView({el: "#troupe-character-relationships-network"});

            /*
            if (!Parse.User.current()) {
                Parse.User.logIn("devuser", "thedumbness");
            }
            */

            // Tells Backbone to start watching for hashchange events
            Parse.history.start();
        },

        // Backbone.js Routes
        routes: {

            // When there is no hash bang on the url, the home method is called
            "": "home",
            "start": "home",
            
            "about": "about",

            "logout": "logout",
            "signup": "signup",
            "reset": "<PASSWORD>",

            "profile": "profile",

            // When #category? is on the url, the category method is called
            "category?:type": "category",

            "victims?:type": "victims",

            "characters?:type": "characters",

            "character?:id": "character",

            "simpletraits/:category/:cid/:type": "simpletraits",

            "simpletrait/:category/:cid/:bid": "simpletrait",
            "simpletrait/specialize/:category/:cid/:bid": "simpletraitspecialize",
            "simpletrait/spacer/:category/:cid/:name/:value/:free_value/new": "simpletraitnew",
            "simpletrait/specialize/:category/:cid/:name/:value/:free_value/new": "simpletrait_new_specialize",
            
            "simpletext/:category/:target/:cid/pick":   "simpletextpick",
            "simpletext/:category/:target/:cid/unpick":   "simpletextunpick",

            "charactercreate/:cid": "charactercreate",

            "charactercreate/simpletraits/:category/:cid/pick/:i": "charactercreatepicksimpletrait",
            "charactercreate/simpletraits/:category/:cid/unpick/:stid/:i": "charactercreateunpicksimpletrait",
            "charactercreate/simpletraits/:category/:cid/specialize/:stid/:i": "charactercreatespecializesimpletrait",
            "charactercreate/simpletext/:category/:target/:cid/pick": "charactercreatepicksimpletext",
            "charactercreate/simpletext/:category/:target/:cid/unpick": "charactercreateunpicksimpletext",
            "charactercreate/complete/:cid": "charactercreatecomplete",

            "characternew": "characternew",

            "character/:cid/print": "characterprint",
            "character/:cid/costs": "charactercosts",
            "character/:cid/log/:start/:changeBy": "characterlog",
            "character/:cid/history/:id": "characterhistory",
            "character/:cid/portrait": "characterportrait",
            "character/:cid/delete": "characterdelete",
            "character/:cid/troupes": "character_list_troupes",
            "character/:cid/troupes/leave": "character_pick_troupe_to_leave",
            "character/:cid/troupes/join": "character_pick_troupe_to_join",
            "character/:cid/troupe/:tid/join": "character_join_troupe",
            "character/:cid/troupe/:tid/leave": "character_leave_troupe",
            "character/:cid/troupe/:tid/show": "character_show_troupe",
            "character/:cid/approval": "characterapproval",
            "character/:cid/rename": "characterrename",
            "character/:cid/approved": "character_show_approved",
            "character/:cid/extendedprinttext": "character_extended_print_text",
            "character/:cid/backgroundlt": "character_background_long_text",
            "character/:cid/noteslt": "character_notes_long_text",

            "character/:cid/experience/:start/:changeBy": "characterexperience",

            "troupe/new": "troupenew",
            "troupes": "troupes",
            "troupe/:id": "troupe",
            "troupe/:id/staff/add": "troupeaddstaff",
            "troupe/:id/staff/edit/:uid": "troupeeditstaff",
            "troupe/:id/characters/:type": "troupecharacters",
            "troupe/:id/characters/summarize/:type": "troupesummarizecharacters",
            "troupe/:id/characters/selecttoprint/:type": "troupe_select_to_print_characters",
            "troupe/:id/characters/print/:type": "troupe_print_characters",
            "troupe/:id/characters/relationships/network": "troupe_relationship_network",
            "troupe/:id/character/:cid": "troupe_character",
            "troupe/:id/portrait": "troupe_portrait",

            "administration": "administration",
            "administration/characters/all": "administration_characters_all",
            "administration/characters/summarize": "administration_characters_summarize",
            "administration/character/:id": "administration_character",
            "administration/users/all": "administration_users",
            "administration/user/:id": "administration_user",
            "administration/patronages/user/:id": "administration_user_patronages",
            "administration/patronages": "administration_patronages",
            "administration/patronage/:id": "administration_patronage",
            "administration/patronages/new": "administration_patronage_new",
            "administration/patronages/new/:userid": "administration_patronage_new",
            "administration/descriptions": "administration_descriptions",

        },

        // Home method
        home: function() {
            var self = this;
            this.enforce_logged_in().then(function () {
                var q = (new Parse.Query(Parse.Role)).equalTo("users", Parse.User.current());
                return q.count();
            }).then(function (count) {
                var user = Parse.User.current();
                if (0 < count) {
                    user.set("storytellerinterface", true);
                } else {
                    user.set("storytellerinterface", false);
                }
                InjectAuthData(user);
                return user.save();
            }).then(function () {
                self.playerOptionsView = self.playerOptionsView || new PlayerOptionsView({el: "#player-options"}).render();
                $.mobile.changePage("#player-options", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },

        logout: function() {
            Parse.User.logOut().always(function () {
                return hello('facebook').logout();
            }).always(function() {
                window.location.hash = "";
                window.location.reload();
            });
        },

        signup: function() {
            if (!Parse.User.current()) {
                // Programatically changes to the categories page
                $.mobile.changePage("#signup", {reverse: false, changeHash: false});
            } else {
                window.location.hash = "";
            }
        },
        
        about: function() {
            $.mobile.changePage("#about", {reverse: false, changeHash: false})
        },

        resetpassword: function() {
            var self = this;
            self.resetPasswordView = self.resetPasswordView || new PasswordResetView({el: "#user-reset-password"});
            self.resetPasswordView.render();
            $.mobile.changePage("#user-reset-password", {reverse: false, changeHash: false});
        },

        profile: function() {
            var self = this;
            self.enforce_logged_in().then(function() {
                return UserChannel.get_users();
            }).then(function() {
                self.set_back_button("#");
                self.userSettingsProfileView = self.userSettingsProfileView || new UserSettingsProfileView().setup();
                $.mobile.changePage("#user-settings-profile", {reverse: false, changeHash: false});
            })
        },

        set_back_button: function(url) {
            $("#header-back-button").attr("href", url);
        },


        charactercosts: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, ["skills", "disciplines", "backgrounds"]).done(function (character) {
                self.characterCostsView.model = character;
                self.characterCostsView.render();
                $.mobile.changePage("#character-costs", {reverse: false, changeHash: false});
            });
        },

        characterlog: function(cid, start, changeBy) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").done(function (character) {
                self.characterLogView.register(character, start, changeBy);
                var activePage = $(".ui-page-active").attr("id");
                var r = $.mobile.changePage("#character-log", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            });
        },

        characterexperience: function(cid, start, changeBy) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").done(function (character) {
                self.characterExperienceView.register(character, start, changeBy);
                var activePage = $(".ui-page-active").attr("id");
                var r = $.mobile.changePage("#experience-notations-all", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            });
        },

        characterhistory: function(cid, id) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterHistoryView.register(character, id).then(function () {
                    var activePage = $(".ui-page-active").attr("id");
                    var r = $.mobile.changePage("#character-history", {reverse: false, changeHash: false});
                    $.mobile.loading("hide");
                });
            }).fail(PromiseFailReport);
        },

        characterapproval: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterApprovalView.register(character).then(function () {
                    var activePage = $(".ui-page-active").attr("id");
                    var r = $.mobile.changePage("#character-approval", {reverse: false, changeHash: false});
                    $.mobile.loading("hide");
                });
            }).fail(PromiseFailReport);
        },

        character_show_approved: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.get_transformed_last_approved();
            }).then(function (transformed) {
                if (null == transformed) {
                    $.mobile.changePage("#character-print-no-approval", {reverse: false, changeHash: false});
                } else {
                    transformed.transform_description = [];
                    self.characterPrintView.setup(transformed);
                    $.mobile.changePage("#printable-sheet", {reverse: false, changeHash: false});
                }
            }).fail(PromiseFailReport);
        },

        characterrename: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                self.characterRenameView = self.characterRenameView || new CharacterRenameView({el: "#character-rename-main"});
                return self.characterRenameView.register(character);
            }).then(function () {
                $.mobile.changePage("#character-rename", {reverse: false, changeHash: false});
            }).always(function () {
                $.mobile.loading("hide");
            }).fail(PromiseFailReport);
        },

        characterprint: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("extended_print_text");
            }).then(function (character) {
                character.transform_description = [];
                self.characterPrintView.setup(character);
                $.mobile.changePage("#printable-sheet", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },

        characternew: function() {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#characters?all");
            self.characterNewView.render();
            $.mobile.changePage("#character-new", {reverse: false, changeHash: false});
        },

        charactercreate: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, []).then(function (character) {
                return character.fetch_all_creation_elements();
            }).done(function (character) {
                self.characterCreateView.model = character;
                self.characterCreateView.render();
                self.characterCreateView.scroll_back_after_page_change();
                $.mobile.changePage("#character-create", {reverse: false, changeHash: false});
                $.mobile.loading("hide");
            }).fail(PromiseFailReport);
        },

        charactercreatepicksimpletrait: function(category, cid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).done(function (c) {
                var specialCategory;
                if ("disciplines" == category) {
                    specialCategory = "in clan disciplines";
                } else if ("wta_gifts" == category) {
                    specialCategory = ["affinity", "show_only_value_1"];
                }
                self.characterCreateSimpleTraitNewView.register(
                    c,
                    category,
                    i,
                    "#charactercreate/<%= self.character.id %>",
                    specialCategory,
                    "#charactercreate/simpletraits/<%= self.category %>/<%= self.character.id %>/specialize/<%= b.linkId() %>/" + i);
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                $.mobile.changePage("#character-create-simpletrait-new", {reverse: false, changeHash: false});
            });
        },


        charactercreatespecializesimpletrait: function(category, cid, stid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                return character.get_trait(category, stid);
            }).then(function (trait, character) {
                return self.simpleTraitSpecializationView.register(
                    character,
                    trait,
                    category,
                    window.location.hash,
                    "#charactercreate/" + character.id
                );
            }).then(function () {
                $.mobile.changePage("#simpletrait-specialization", {reverse: false, changeHash: false});
            }).fail(function(error) {
                console.log(error.message);
            });
        },

        charactercreateunpicksimpletrait: function(category, cid, stid, i) {
            var self = this;
            i = _.parseInt(i);
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                return character.unpick_from_creation(category, stid, i);
            }).done(function (c) {
                window.location.hash = "#charactercreate/" + c.id;
            }).fail(function(error) {
                console.log(error.message);
            });
        },

        charactercreatepicksimpletext: function(category, target, cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).done(function (c) {
                self.simpleTextNewView.register(c, category, target, "#charactercreate/" + c.id);
                self.characterCreateView.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                $.mobile.changePage("#simpletext-new", {reverse: false, changeHash: false});
            });
        },
        
        charactercreateunpicksimpletext: function(category, target, cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid, [category]).then(function (character) {
                self.character.backToTop = document.documentElement.scrollTop || document.body.scrollTop;
                return character.unpick_text(target);
            }).then(function (c) {
                window.location.hash = "#charactercreate/" + c.id;
            }).fail(PromiseFailReport);
        },
        
        charactercreatecomplete: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#charactercreate/" + cid);
            self.get_character(cid).done(function (c) {
                return c.complete_character_creation();
            }).then(function () {
                window.location.hash = "#character?" + cid;
            }).fail(function (error) {
                alert(error.message);
                window.location.hash = "#charactercreate/" + cid;
            }).fail(PromiseFailReport);
        },

        characterportrait: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid).done(function (c) {
                return self.characterPortraitView.register(c);
            }).always(function() {
                $.mobile.changePage("#character-portrait", {reverse: false, changeHash: false});
            });
        },
        
        character_extended_print_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("extended_print_text");
            }).then(function (character) {
                character.transform_description = [];
                self.cept = self.cept || new CharacterLongTextView({
                    el: "#extended-print-text",
                });
                self.cept.setup(
                    character,
                    {
                        category: "extended_print_text",
                        pretty: "Extended Print Text",
                        description: "Additional text to display with your printed character sheet.",                       
                    });
                $.mobile.changePage("#extended-print-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport);
        },
        
        character_background_long_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("background");
            }).then(function (character) {
                character.transform_description = [];
                self.clt = self.clt || new CharacterLongTextView({
                    el: "#long-text",
                });
                self.clt.setup(
                    character,
                    {
                        category: "background",
                        pretty: "Background",
                        description: "History and backstory for your character.",                       
                    });
                $.mobile.changePage("#long-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport).always(function() {
                $.mobile.loading("hide");
            });
        },
        
        character_notes_long_text: function(cid) {
            var self = this;
            $.mobile.loading("show");
            self.set_back_button("#character?" + cid);
            self.get_character(cid, "all").then(function (character) {
                return character.fetch_long_text("notes");
            }).then(function (character) {
                character.transform_description = [];
                self.clt = self.clt || new CharacterLongTextView({
                    el: "#long-text",
                });
                self.clt.setup(
                    character,
                    {
                        category: "notes",
                        pretty: "Notes",
                        description: "Notes about your character's interactions and progression",
                    });
                $.mobile.changePage("#long-text", {reverse: false, changeHash: false});
            }).fail(PromiseFailReport).always(function() {
                $.mobile.loading("hide");
            });
        },
        
        show_character_helper: function(id, back_url) {
            $.mobile.loading("show");
            this.set_back_button(back_url);
            var c = this.character;
            this.get_character(id).done(function (m) {
                c.model = m;
                c.render();
                c.scroll_back_after_page_change();
                $.mobile.changePage("#character", {reverse: false, changeHash:false});
            }).then(function () {
                $.mobile.loading("hide");
            }).fail(PromiseFailReport).fail(function () {
                window.location.hash = back_url;
            });
        },

        character: function(id) {
            this.show_character_helper(id, "#characters?all");
        },

        troupe_character: function(id, cid) {
            this.show_character_helper(cid, "#troupe/" + id + "/characters/all");
        },

        administration_character: function(id) {
            this.show_character_helper(id, "#administration/characters/all");
        },

        administration_users: function() {
{'fraction_non_alphanumeric': 0.1331701913060732, 'fraction_numerical': 6.613865970006118e-05, 'mean_word_length': 1.9806318072051647, 'pattern_counts': {'":': 138, '<': 15, '<?xml version=': 0, '>': 17, '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': '1203429', 'n_tokens_mistral': 15564, 'n_tokens_neox': 15336, 'n_words': 2439}