/**
 * @fileoverview Rule to enforce var declarations are only at the top of a function.
 * @author Danny Fritz
 */
"use strict";

var _ = require("lodash");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function (context) {
    var errorMessage = "All \"var\" declarations must be at the top of the function scope.";

    //--------------------------------------------------------------------------
    // Helpers
    //--------------------------------------------------------------------------
    function report(node) {
        context.report(node, errorMessage);
    }

    function hasVars (statements) {
        var variableDeclarationIndex;
        variableDeclarationIndex = _.indexOf(statements, "VariableDeclaration");
        if (variableDeclarationIndex >= 0) {
            return true;
        }
        return false;
    }

    function pruneStatements (statements) {console.log(statements);
        var prunedStatements;
        prunedStatements = _.map(statements, function (statement) {
            return statement.type;
        });
        return prunedStatements;
    }

    function areVarsOnTop (statements) {
        var lastVariableDeclaration;
        var numberOfVariableDeclarations;
        lastVariableDeclaration = _.lastIndexOf(statements, "VariableDeclaration");
        numberOfVariableDeclarations = _.reduce(statements,
            function (sum, statement) {
                if (statement === "VariableDeclaration") {
                    return sum + 1;
                }
                return sum;
            }, 0);
        if (numberOfVariableDeclarations <= lastVariableDeclaration) {
            return false;
        }
        return true;
    }

    function checkFunctionForVarsOnTop (node) {
        var statements;
        statements = pruneStatements(node.body.body);
        if (areVarsOnTop(statements, node) === false) {
            report(node);
        }
    }

    function checkForForVars (node) {
        var statements;
        if (node.init.type === "VariableDeclaration") {
            report(node);
        }
        statements = pruneStatements(node.body.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkForInForVars (node) {
        var statements;
        if (node.left.type === "VariableDeclaration") {
            report(node);
        }
        statements = pruneStatements(node.body.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkIfForVars (node) {
        var statements;
        statements = pruneStatements(node.consequent.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkCaseForVars (node) {
        var statements;
        statements = pruneStatements(node.consequent);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkTryForVars (node) {
        var statements;
        statements = pruneStatements(node.block.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkCatchForVars (node) {
        var statements;
        statements = pruneStatements(node.body.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    function checkWhileForVars (node) {
        var statements;
        statements = pruneStatements(node.body.body);
        if (hasVars(statements)) {
            report(node);
        }
    }

    //--------------------------------------------------------------------------
    // Public API
    //--------------------------------------------------------------------------

    return {
        "FunctionDeclaration": checkFunctionForVarsOnTop,
        "ForStatement": checkForForVars,
        "ForInStatement": checkForInForVars,
        "IfStatement": checkIfForVars,
        "SwitchCase": checkCaseForVars,
        "TryStatement": checkTryForVars,
        "CatchClause": checkCatchForVars,
        "WhileStatement": checkWhileForVars,
        "DoWhileStatement": checkWhileForVars
    };

};

@@ -128,36 +128,8 @@
 %22;%0A%0A
-var _ = require(%22lodash%22);%0A%0A
 //--
@@ -807,18 +807,8 @@
 x = 
-_.indexOf(
 stat
@@ -805,34 +805,41 @@
 dex = statements
-, 
+.indexOf(
 %22VariableDeclara
@@ -1084,14 +1084,8 @@
 s = 
-_.map(
 stat
@@ -1090,18 +1090,21 @@
 atements
-, 
+.map(
 function
@@ -1359,17 +1359,26 @@
 ation = 
-_
+statements
 .lastInd
@@ -1382,28 +1382,16 @@
 IndexOf(
-statements, 
 %22Variabl
@@ -1449,17 +1449,8 @@
 s = 
-_.reduce(
 stat
@@ -1459,22 +1459,16 @@
 ents
-,%0A            
+.reduce(
 func

Remove dependency on LoDash.