<commit_before>/*jslint plusplus: true, vars: true, nomen: true */
/*global $, brackets, define, Mustache */

define(function (require, exports) {
    "use strict";
    
    var _                       = brackets.getModule("thirdparty/lodash"),
        CommandManager          = brackets.getModule("command/CommandManager"),
        Dialogs                 = brackets.getModule("widgets/Dialogs"),
        EditorManager           = brackets.getModule("editor/EditorManager"),
        FileSystem              = brackets.getModule("filesystem/FileSystem"),
        Menus                   = brackets.getModule("command/Menus"),
        PopUpManager            = brackets.getModule("widgets/PopUpManager"),
        SidebarView             = brackets.getModule("project/SidebarView");
    
    var q                       = require("../thirdparty/q"),
        ErrorHandler            = require("./ErrorHandler"),
        Main                    = require("./Main"),
        Panel                   = require("./Panel"),
        Strings                 = require("../strings"),
        branchesMenuTemplate    = require("text!htmlContent/git-branches-menu.html"),
        questionDialogTemplate  = require("text!htmlContent/git-question-dialog.html");

    var $gitBranchName          = $(null),
        $dropdown;

    function renderList(branches) {
        var currentBranch = _.find(branches, function (b) { return b.indexOf("* ") === 0; }),
            templateVars  = {
                branchList : _.without(branches, currentBranch),
                Strings     : Strings
            };
        return Mustache.render(branchesMenuTemplate, templateVars);
    }

    function closeDropdown() {
        if ($dropdown) {
            PopUpManager.removePopUp($dropdown);
        }
        detachCloseEvents();
    }

    function handleEvents() {
        $dropdown.on("click", "a.git-branch-new", function (e) {
            e.stopPropagation();

            var compiledTemplate = Mustache.render(questionDialogTemplate, {
                title: Strings.CREATE_NEW_BRANCH,
                question: Strings.BRANCH_NAME,
                stringInput: true,
                Strings: Strings
            });
            var dialog  = Dialogs.showModalDialogUsingTemplate(compiledTemplate);
            dialog.getElement().find("input").focus();
            dialog.done(function (buttonId) {
                if (buttonId === "ok") {
                    var branchName = dialog.getElement().find("input").val().trim();
                    Main.gitControl.createBranch(branchName).fail(function (err) {
                        ErrorHandler.showError(err, "Creating new branch failed");
                    }).then(function () {
                        closeDropdown();
                        // refresh should not be necessary in the future and trigerred automatically by Brackets, remove then
                        CommandManager.execute("file.refresh");
                    });
                }
            });

        }).on("click", "a.git-branch-link", function (e) {
            e.stopPropagation();
            var branchName = $(this).data("branch");
            Main.gitControl.checkoutBranch(branchName).fail(function (err) {
                ErrorHandler.showError(err, "Switching branches failed");
            }).then(function () {
                closeDropdown();
                // refresh should not be necessary in the future and trigerred automatically by Brackets, remove then
                CommandManager.execute("file.refresh");
            });
        }).on("mouseenter", "a", function () {
            $(this).addClass("selected");
        }).on("mouseleave", "a", function () {
            $(this).removeClass("selected");
        });
    }

    function attachCloseEvents() {
        $("html").on("click", closeDropdown);
        $("#project-files-container").on("scroll", closeDropdown);
        $(SidebarView).on("hide", closeDropdown);
        $("#titlebar .nav").on("click", closeDropdown);
        // $(window).on("keydown", keydownHook);
    }

    function detachCloseEvents() {
        $("html").off("click", closeDropdown);
        $("#project-files-container").off("scroll", closeDropdown);
        $(SidebarView).off("hide", closeDropdown);
        $("#titlebar .nav").off("click", closeDropdown);
        // $(window).off("keydown", keydownHook);

        $dropdown = null;
        EditorManager.focusEditor();
    }

    function toggleDropdown(e) {
        e.stopPropagation();

        // If the dropdown is already visible, close it
        if ($dropdown) {
            closeDropdown();
            return;
        }

        Menus.closeAll();

        Main.gitControl.getBranches().fail(function (err) {
            ErrorHandler.showError(err, "Getting branch list failed");
        }).then(function (branches) {
            $dropdown = $(renderList(branches));

            var toggleOffset = $gitBranchName.offset();
            $dropdown
                .css({
                    left: toggleOffset.left,
                    top: toggleOffset.top + $gitBranchName.outerHeight()
                })
                .appendTo($("body"));

            PopUpManager.addPopUp($dropdown, detachCloseEvents, true);
            attachCloseEvents();
            handleEvents();
        });
    }
    
    function _isRepository() {
        return Main.gitControl.getGitStatus().then(function () {
            return true;
        }).fail(function (err) {
            if (err.match(/not a git repository/i)) {
                return false;
            }
            throw err;
        });
    }

    function _isRepositoryRoot() {
        var currentFolder = Main.getProjectRoot();
        return q.ninvoke(FileSystem, "resolve", currentFolder).spread(function (directory) {
            return q.ninvoke(directory, "getContents");
        }).spread(function (contents) {
            return _.any(contents, function (content) { return content.name === ".git"; });
        });
    }

    function refresh() {
        // show info that branch is refreshing currently
        $gitBranchName
            .text("\u2026")
            .parent()
                .show();

        return _isRepository().then(function (isRepo) {
            $gitBranchName.parent().toggle(isRepo);

            if (!isRepo) {
                $gitBranchName
                    .off("click")
                    .text("not a git repo");
                Panel.disable("not-repo");
                return;
            }

            return _isRepositoryRoot().then(function (isRepositoryRoot) {
                if (!isRepositoryRoot) {
                    $gitBranchName
                        .off("click")
                        .text("not a git root");
                    Panel.disable("not-root");
                    return;
                }

                return Main.gitControl.getBranchName().then(function (branchName) {
                    $gitBranchName.text(branchName)
                        .off("click")
                        .on("click", toggleDropdown)
                        .append($("<span class='dropdown-arrow' />"));
                    Panel.enable();
                }).fail(function (ex) {
                    if (ex.match(/unknown revision/)) {
                        $gitBranchName
                            .off("click")
                            .text("no branch");
                        Panel.enable();
                    } else {
                        throw ex;
                    }
                });
            });
        }).fail(function (err) {
            throw ErrorHandler.showError(err);
        });
    }
    
    function init() {
        // Add branch name to project tree
        $gitBranchName = $("<span id='git-branch'></span>");<commit_msg>Fix not a git root<commit_after>/*jslint plusplus: true, vars: true, nomen: true */
/*global $, brackets, define, Mustache */

define(function (require, exports) {
    "use strict";
    
    var _                       = brackets.getModule("thirdparty/lodash"),
        CommandManager          = brackets.getModule("command/CommandManager"),
        Dialogs                 = brackets.getModule("widgets/Dialogs"),
        EditorManager           = brackets.getModule("editor/EditorManager"),
        FileSystem              = brackets.getModule("filesystem/FileSystem"),
        Menus                   = brackets.getModule("command/Menus"),
        PopUpManager            = brackets.getModule("widgets/PopUpManager"),
        SidebarView             = brackets.getModule("project/SidebarView");
    
    var q                       = require("../thirdparty/q"),
        ErrorHandler            = require("./ErrorHandler"),
        Main                    = require("./Main"),
        Panel                   = require("./Panel"),
        Strings                 = require("../strings"),
        branchesMenuTemplate    = require("text!htmlContent/git-branches-menu.html"),
        questionDialogTemplate  = require("text!htmlContent/git-question-dialog.html");

    var $gitBranchName          = $(null),
        $dropdown;

    function renderList(branches) {
        var currentBranch = _.find(branches, function (b) { return b.indexOf("* ") === 0; }),
            templateVars  = {
                branchList : _.without(branches, currentBranch),
                Strings     : Strings
            };
        return Mustache.render(branchesMenuTemplate, templateVars);
    }

    function closeDropdown() {
        if ($dropdown) {
            PopUpManager.removePopUp($dropdown);
        }
        detachCloseEvents();
    }

    function handleEvents() {
        $dropdown.on("click", "a.git-branch-new", function (e) {
            e.stopPropagation();

            var compiledTemplate = Mustache.render(questionDialogTemplate, {
                title: Strings.CREATE_NEW_BRANCH,
                question: Strings.BRANCH_NAME,
                stringInput: true,
                Strings: Strings
            });
            var dialog  = Dialogs.showModalDialogUsingTemplate(compiledTemplate);
            dialog.getElement().find("input").focus();
            dialog.done(function (buttonId) {
                if (buttonId === "ok") {
                    var branchName = dialog.getElement().find("input").val().trim();
                    Main.gitControl.createBranch(branchName).fail(function (err) {
                        ErrorHandler.showError(err, "Creating new branch failed");
                    }).then(function () {
                        closeDropdown();
                        // refresh should not be necessary in the future and trigerred automatically by Brackets, remove then
                        CommandManager.execute("file.refresh");
                    });
                }
            });

        }).on("click", "a.git-branch-link", function (e) {
            e.stopPropagation();
            var branchName = $(this).data("branch");
            Main.gitControl.checkoutBranch(branchName).fail(function (err) {
                ErrorHandler.showError(err, "Switching branches failed");
            }).then(function () {
                closeDropdown();
                // refresh should not be necessary in the future and trigerred automatically by Brackets, remove then
                CommandManager.execute("file.refresh");
            });
        }).on("mouseenter", "a", function () {
            $(this).addClass("selected");
        }).on("mouseleave", "a", function () {
            $(this).removeClass("selected");
        });
    }

    function attachCloseEvents() {
        $("html").on("click", closeDropdown);
        $("#project-files-container").on("scroll", closeDropdown);
        $(SidebarView).on("hide", closeDropdown);
        $("#titlebar .nav").on("click", closeDropdown);
        // $(window).on("keydown", keydownHook);
    }

    function detachCloseEvents() {
        $("html").off("click", closeDropdown);
        $("#project-files-container").off("scroll", closeDropdown);
        $(SidebarView).off("hide", closeDropdown);
        $("#titlebar .nav").off("click", closeDropdown);
        // $(window).off("keydown", keydownHook);

        $dropdown = null;
        EditorManager.focusEditor();
    }

    function toggleDropdown(e) {
        e.stopPropagation();

        // If the dropdown is already visible, close it
        if ($dropdown) {
            closeDropdown();
            return;
        }

        Menus.closeAll();

        Main.gitControl.getBranches().fail(function (err) {
            ErrorHandler.showError(err, "Getting branch list failed");
        }).then(function (branches) {
            $dropdown = $(renderList(branches));

            var toggleOffset = $gitBranchName.offset();
            $dropdown
                .css({
                    left: toggleOffset.left,
                    top: toggleOffset.top + $gitBranchName.outerHeight()
                })
                .appendTo($("body"));

            PopUpManager.addPopUp($dropdown, detachCloseEvents, true);
            attachCloseEvents();
            handleEvents();
        });
    }
    
    function _isRepositoryRoot() {
        var gitFolder = Main.getProjectRoot() + "/.git",
            defer = q.defer();
        FileSystem.resolve(gitFolder, function (err, directory) {
            defer.resolve(directory && !err ? true : false);
        });
        return defer.promise;
    }

    function refresh() {
        // show info that branch is refreshing currently
        $gitBranchName
            .text("\u2026")
            .parent()
                .show();

        return _isRepositoryRoot().then(function (isRepositoryRoot) {
            $gitBranchName.parent().toggle(isRepositoryRoot);

            if (!isRepositoryRoot) {
                $gitBranchName
                    .off("click")
                    .text("not a git repo");
                Panel.disable("not-repo");
                return;
            }
            
            return Main.gitControl.getBranchName().then(function (branchName) {
                $gitBranchName.text(branchName)
                    .off("click")
                    .on("click", toggleDropdown)
                    .append($("<span class='dropdown-arrow' />"));
                Panel.enable();
            }).fail(function (ex) {
                if (ex.match(/unknown revision/)) {
                    $gitBranchName
                        .off("click")
                        .text("no branch");
                    Panel.enable();
                } else {
                    throw ex;
                }
            });
        }).fail(function (err) {
            throw ErrorHandler.showError(err);
        });
    }
    
    function init() {
        // Add branch name to project tree
        $gitBranchName = $("<span id='git-branch'></span>");
{'fraction_non_alphanumeric': 0.1303997312730937, 'fraction_numerical': 0.0006718172657037286, 'mean_word_length': 1.6175487954985053, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '4174261', 'n_tokens_mistral': 3762, 'n_tokens_neox': 3589, 'n_words': 689}