﻿
"use strict";

// Service for voting functionality
app.factory("votingService", ["$rootScope",
    "$http",
    "$location",
    "$anchorScroll",
    "ngAuthSettings",
    "votingDataService",
    "judgeRulesService",
    "$sce",
    "databaseRefs",
    "$log",
    "$q",
    "$window",
    function ($rootScope,
        $http,
        $location,
        $anchorScroll,
        ngAuthSettings,
        votingDataService,
        judgeRulesService,
        $sce,
        databaseRefs,
        $log,
        $q,
        $window) {
        var votingFactory = {};
        var $scope = votingFactory; // Alias
        var fingerprintPromise = null;

        function _setFingerprint() {
            var deferred = $q.defer();
            fingerprintPromise = deferred.promise;

            if ($window.requestIdleCallback) {
                $window.requestIdleCallback(function () {
                    _performFingerprint(deferred);
                })
            } else {
                setTimeout(function () {
                    _performFingerprint(deferred);
                }, 500)
            }
        }

        function _performFingerprint(deferred) {
            if ($window.Fingerprint2) {
                $window.Fingerprint2.get(function (components) {
                    var fingerprint = $window.Fingerprint2.x64hash128(components.map(function (pair) { return pair.value }).join(), 31);
                    deferred.resolve(fingerprint);
                })
            }
            else {
                deferred.resolve('blocked');
            }
        }

        _setFingerprint();

        // Voting templates    
        $scope.orderedListTemplateName = "orderedVoteList";
        $scope.unorderedListTemplateName = "unorderedVoteList";
        $scope.criteriaVoteTemplateName = "criteriaVotePanel";
        $scope.criteriaListVoteTemplateName = "criteriaListVotePanel";
        $scope.votingControlsTemplateBaseUri = window.location.pathname + "/spa-app/views/fragments/html/";
        $scope.votingControlTemplate = null;

        $scope.voteTypeId = 0;
        $scope.voteTypeConfig = {};
        $scope.currentCategory = { id: 0 };
        $scope.votes = [];

        $scope.curCriteriaVotingInfo = { voteId: 0, subId: 0, nominee: '', voteSubmitted: 0, singleBest: 0, ballotId: 0 };
        $scope.curCriteriaVotes = {};
        $scope.criteriaVotesUIInfo = {};
        $scope.showVotingDetailsButton = false;

        // ----- Helpers
        var _init = function (voteTypeId, voteTypeConfig, category) {
            votingFactory.voteTypeId = voteTypeId;
            votingFactory.votingEnabled = voteTypeId != databaseRefs.voteType.NO_VOTE;
            votingFactory.voteTypeConfig = voteTypeConfig;
            votingFactory.currentCategory = category;

            // Get the votes for the configured category, return the promise
            if ($scope.voteTypeConfig && ($scope.voteTypeConfig.unorderedList ||
                $scope.voteTypeConfig.unorderedListWithWriteIns)) {
                // Configure vote panel
                $scope.votingControlTemplate = $scope.votingControlsTemplateBaseUri + $scope.unorderedListTemplateName;

                // Call getVotes with a sortType param
                return votingDataService.getVotes($scope.currentCategory.id, "asc").then(function (results) {
                    $scope.votes = results.data;
                });
            }
            else {
                // Configure Vote panel
                if ($scope.voteTypeConfig && ($scope.voteTypeConfig.orderedList ||
                    $scope.voteTypeConfig.orderedListWithWriteIns))
                    $scope.votingControlTemplate = $scope.votingControlsTemplateBaseUri + $scope.orderedListTemplateName;
                else {
                    // Determine if we're working with a normal criteria vote panel or a "display as list" version
                    if ($scope.voteTypeConfig && $scope.voteTypeConfig.criteria && $scope.voteTypeConfig.criteria.displayCriteriaAsList)
                        $scope.votingControlTemplate = $scope.votingControlsTemplateBaseUri + $scope.criteriaListVoteTemplateName;
                    else
                        $scope.votingControlTemplate = $scope.votingControlsTemplateBaseUri + $scope.criteriaVoteTemplateName;
                    $scope.showVotingDetailsButton = true;
                    if ($scope.voteTypeConfig) {
                        $scope.voteTypeConfig.rules = $sce.trustAsHtml($scope.voteTypeConfig.rules);
                    }
                }

                // Call getVotes without any sort param (sort order by default)
                return votingDataService.getVotes($scope.currentCategory.id).then(function (results) {
                    $scope.votes = results.data;
                });
            }
        };
        var _getVoteTemplatePath = function () {
            return ($scope.currentVotingControlTemplate);
        };
        var _isCategorySubmitted = function () {
            return ($scope.currentCategory.submitted === 1);
        };
        var _inVotesBySubmissionId = function (subId) {
            return $.grep($scope.votes, function (vote) {
                return (vote.submissionId == subId);
            }).length > 0;
        };
        var _isCriteriaVoting = function () {
            return ($scope.voteTypeConfig && $scope.voteTypeConfig.criteria);
        };
        var _isSingleBestEnabled = function () {
            var result = (_isCriteriaVoting() && $scope.voteTypeConfig.criteria.enableSingleBestSelection);
            return result;
        };
        var _getCriteriaListNumber = function (n) {
            return (new Array(n));
        };
        var _checkSelectedCriteriaListVote = function (criteriaName, number) {
            return ($scope.curCriteriaVotes[criteriaName] && $scope.curCriteriaVotes[criteriaName] == parseInt(number));
        };
        var _getCriteriaNumericLabel = function (idRef) {
            var numericLabel = "";
            if ($scope.voteTypeConfig.criteria && $scope.voteTypeConfig.criteria.numericLabels) {
                var found = $.grep($scope.voteTypeConfig.criteria.numericLabels, function (x) {
                    return (x.refIdentifier == idRef);
                });
                if (found.length == 1)
                    numericLabel = found[0].label;
            }
            return numericLabel;
        };
        function _canMakeWriteIn() {
            var categoryWasSubmitted = $scope.isCategorySubmitted();
            var currentVoteTypeConfiguration = _getCurrentVoteTypeConfiguration();

            if (categoryWasSubmitted || !currentVoteTypeConfiguration) {
                return false;
            }

            var hasRemainingVotes = $scope.votes.length < currentVoteTypeConfiguration.voteCount;
            return hasRemainingVotes;
        }
        var _canVote = function (voteId) {
            if (!$scope.voteTypeConfig) {
                $log.error("$scope.voteTypeConfig is not defined");
                return false;
            }

            var categoryWasSubmitted = $scope.isCategorySubmitted();
            var voteIsAlreadyCreated = voteId != 0;
            var currentVoteTypeConfiguration = _getCurrentVoteTypeConfiguration();

            if (categoryWasSubmitted || voteIsAlreadyCreated || !currentVoteTypeConfiguration) {
                return false;
            }

            var hasRemainingVotes = $scope.votes.length < currentVoteTypeConfiguration.voteCount;
            return hasRemainingVotes;
        };

        function _getCurrentVoteTypeConfiguration() {
            if ($scope.voteTypeConfig.orderedList) {
                return $scope.voteTypeConfig.orderedList;
            }
            else if ($scope.voteTypeConfig.unorderedList) {
                return $scope.voteTypeConfig.unorderedList;
            }
            else if ($scope.voteTypeConfig.unorderedListWithWriteIns) {
                return $scope.voteTypeConfig.unorderedListWithWriteIns;
            }
            else if ($scope.voteTypeConfig.orderedListWithWriteIns) {
                return $scope.voteTypeConfig.orderedListWithWriteIns;
            }
            return null;
        }
        function _isOrderedVoting() {
            if ($scope.voteTypeConfig.orderedList || $scope.voteTypeConfig.orderedListWithWriteIns) {
                return true;
            }
            return false;
        }

        function _hasWriteIns() {
            if ($scope.voteTypeConfig.unorderedListWithWriteIns || $scope.voteTypeConfig.orderedListWithWriteIns) {
                return true;
            }
            return false;
        }

        var _canVoteBySubmissionId = function (submissionId) {
            if (!$scope.voteTypeConfig) {
                $log.error("$scope.voteTypeConfig is not defined");
                return false;
            }

            var categoryWasSubmitted = $scope.isCategorySubmitted();
            var submissionHasVote = $scope.inVotesBySubmissionId(submissionId);
            var currentVoteTypeConfiguration = _getCurrentVoteTypeConfiguration();

            if (categoryWasSubmitted || submissionHasVote || !currentVoteTypeConfiguration) {
                return false;
            }

            var hasRemainingVotes = $scope.votes.length < currentVoteTypeConfiguration.voteCount;
            return hasRemainingVotes;
        };
        var _canDeleteVote = function (voteId) {
            return (!$scope.isCategorySubmitted() && voteId > 0 && $scope.votes.length > 0)
        }
        var _showSubmitVotes = function () {
            var result = false;
            return result;
            var submitted = $scope.isCategorySubmitted();

            if (!submitted) {
                if (typeof $scope.voteTypeConfig !== "undefined" && $scope.voteTypeConfig !== null) {
                    if (typeof $scope.voteTypeConfig.orderedList !== "undefined" && $scope.voteTypeConfig.orderedList !== null) {
                        if ($scope.votes.length == $scope.voteTypeConfig.orderedList.voteCount) {
                            result = true;
                        }
                    }
                    else if (typeof $scope.voteTypeConfig.unorderedList !== "undefined" && $scope.voteTypeConfig.unorderedList !== null) {
                        if ($scope.votes.length == $scope.voteTypeConfig.unorderedList.voteCount) {
                            result = true;
                        }
                    }
                    else if (typeof $scope.voteTypeConfig.criteria !== "undefined" && $scope.voteTypeConfig.criteria !== null) {
                        result = true;
                    }
                }
            }

            return result;
        };
        function _getVoteDisplayInfo(vote) {
            var result = '';
            if (vote.details && vote.details.writeIn) {
                result = vote.details.writeIn.field1;

                if (vote.details.writeIn.field2) {
                    result += '<br />' + vote.details.writeIn.field2;
                }
                if (vote.details.writeIn.field3) {
                    result += '<br />' + vote.details.writeIn.field3;
                }
                return result;
            }

            var result = vote.nominee;
            if (vote.nomineeSecondaryName) {
                result += '<br />' + vote.nomineeSecondaryName;
            }
            if (vote.thirdName) {
                result += '<br />' + vote.thirdName;
            }
            return result;
        }
        var _showCriteriaSubmitVotes = function () {
            var showSubmitVotes = false;

            // We have to make sure that they have voted on all criteria
            if ($scope.curCriteriaVotes) {
                for (var key in $scope.curCriteriaVotes) {
                    showSubmitVotes = true;
                    if ($scope.curCriteriaVotes[key] == null) {
                        showSubmitVotes = false;
                        break;
                    }
                } // for
            }

            if (typeof judgeRulesService.showIndividualCriteriaVoteSubmitButtons === "function")
                return (judgeRulesService.showIndividualCriteriaVoteSubmitButtons() && !$scope.isCategorySubmitted() && showSubmitVotes);

            return (!$scope.isCategorySubmitted() && showSubmitVotes);
        };
        var _showVoteUp = function (index) {
            return (!$scope.isCategorySubmitted() && index > 0);
        };
        var _showVoteDown = function (index) {
            return (!$scope.isCategorySubmitted() && index != ($scope.votes.length - 1));
        };
        var _showEmptyRowUIFix = function (voteId) {
            return !($scope.canVote(voteId) || $scope.canDeleteVote(voteId));
        };
        var _resetCriteriaVotePanel = function () {
            $scope.curCriteriaVotingInfo.voteId = 0;
            $scope.curCriteriaVotingInfo.subId = 0;
            $scope.curCriteriaVotingInfo.nominee = "";
            $scope.curCriteriaVotingInfo.voteSubmitted = 0;
            $scope.curCriteriaVotingInfo.singleBest = 0;
            $scope.curCriteriaVotingInfo.ballotId = 0;

            $scope.curCriteriaVotes = {};
            $scope.criteriaVotesUIInfo = {};
        };
        var _showCriteriaVoteDetails = function (voteId, subId, nominee, voteSubmitted, scrollTop, ballotId) {
            $scope.curCriteriaVotingInfo.voteId = voteId;
            $scope.curCriteriaVotingInfo.subId = subId;
            $scope.curCriteriaVotingInfo.nominee = nominee;
            $scope.curCriteriaVotingInfo.voteSubmitted = voteSubmitted;
            $scope.curCriteriaVotingInfo.ballotId = ballotId;

            var foundVote = $.grep($scope.votes, function (vote) {
                return (vote.submissionId == subId);
            })[0];

            // Set the single best if applicable
            if (_isSingleBestEnabled() && foundVote && foundVote.details.criteria && foundVote.details.criteria.singleBest)
                $scope.curCriteriaVotingInfo.singleBest = foundVote.details.criteria.singleBest ? 1 : 0;
            else {
                $scope.curCriteriaVotingInfo.singleBest = 0;
            }
            // Based on how many criteria are set, we'll create that many criteria vote entries        
            for (var i = 0; i < $scope.voteTypeConfig.criteria.criteriaFields.length; i++) {
                var criteriaField = $scope.voteTypeConfig.criteria.criteriaFields[i];

                // Check if we found a vote earlier, set this value
                var voteValue = null;
                if (foundVote && foundVote.details && foundVote.details.criteria && foundVote.details.criteria.criteriaFields) {
                    voteValue = $.grep(foundVote.details.criteria.criteriaFields, function (cf) {
                        return ((cf.name == criteriaField.name));
                    })[0].value;
                }

                $scope.curCriteriaVotes[criteriaField.name] = voteValue;
                if (voteValue == null) {
                    $scope.criteriaVotesUIInfo[criteriaField.name] = { overStar: 0, percent: 0, lastValue: 0 };
                }
                else {
                    // if there is value, populate the field so that it will show on UI
                    $scope.criteriaVotesUIInfo[criteriaField.name] = { overStar: voteValue, percent: 100 * (voteValue / criteriaField.maximumValue), starRatingHoverLabel: judgeRulesService.getStarRatingLabel(voteValue), lastValue: voteValue };
                }
            } // for

            if (scrollTop) {
                // Set location hash for anchorscroll
                $location.hash("top");
                $anchorScroll();
            }
        };
        var _refresh = function (eventType, voteId) {
            var deferred = $q.defer();

            votingDataService.getVotes($scope.currentCategory.id).then(function (results) {
                $scope.votes = results.data;

                // Broadcast specific event types if applicable, we won't broadcast them all, to maintain some efficiency
                if (eventType) {
                    switch (eventType) {
                        case 'set':
                            $rootScope.$broadcast('refreshVotesRequired');
                            $rootScope.$broadcast('setVote');
                            break;
                        case 'moveup':
                        case 'movedown':
                            $rootScope.$broadcast('swapVote');
                            break;
                        case 'delete':
                            $rootScope.$broadcast('refreshVotesRequired');
                            $rootScope.$broadcast('deleteVote', voteId);
                            break;
                        case 'submit':
                            $rootScope.$broadcast('submitVote');
                            break;
                        default:
                            $rootScope.$broadcast('refreshVotesRequired');
                            break;
                    } // switch
                } // if

                deferred.resolve();
            }).catch(function () {
                deferred.reject();
            });

            return deferred.promise;
        };
        var _getVotes = function () {
            return ($scope.votes);
        };
        var _deleteVotes = function () {
            console.i('delete votes');
        };
        var _deleteVotesByCategoryId = function (categoryId) {
            votingDataService.deleteVotesByCategoryId(categoryId);
        };
        var _deleteVote = function (voteId) {
            var deferred = $q.defer();

            votingDataService.deleteVote(voteId).then(function (results) {
                $scope.refresh('delete', voteId).then(function () {
                    deferred.resolve();
                });
            },
                function (error) {
                    console.error('error deleting vote');
                    deferred.reject();
                });

            return deferred.promise;
        };
        var _deleteVoteBySubmissionId = function (subId) {
            console.i('delete vote by subId: ' + subId);
            var vote = $.grep($scope.votes, function (v) {
                return (v.submissionId == subId);
            });
            $scope.deleteVote(vote[0].voteId);
        };
        var _setVote = function (subId, ballotId) {
            console.i('setting vote for: ' + subId + ' ballot id: ' + ballotId);

            var sortOrder = _getSortOrder();

            fingerprintPromise.then(function (fingerprint) {
                votingDataService.setVote(subId, sortOrder, fingerprint, ballotId).then(function (results) {
                    $scope.refresh('set');
                },
                    function (error) {
                        console.error('error setting vote');
                    });
            });
        };
        function _getSortOrder() {
            var lastVote = $scope.votes[$scope.votes.length - 1];
            var sortOrder = 1;
            if (lastVote) {
                sortOrder = lastVote.sortOrder + 1;
            }
            return sortOrder;
        }
        var _setUnrankedVote = function (subId, ballotId) {
            console.i('setting vote for: ' + subId + ' ballot id: ' + ballotId);
            fingerprintPromise.then(function (fingerprint) {
                votingDataService.setVote(subId, null, fingerprint, ballotId).then(function (results) {
                    $scope.refresh('set');
                },
                    function (error) {
                        console.error('error setting vote');
                    });
            });
        };
        function _setWriteInVote(writeIn, ballotId) {
            var sortOrder = null;
            if (_isOrderedVoting()) {
                sortOrder = _getSortOrder();
            }

            var promise = fingerprintPromise.then(function (fingerprint) {
                votingDataService.setWriteInVote(writeIn, sortOrder, fingerprint, ballotId);
                promise.then(function () {
                    $scope.refresh('set');
                })
                    .catch(function () {
                        $.awards.alert({
                            title: "Error",
                            message: "Failed to create vote. Please contact support."
                        });
                    });
            });
            return promise;
        }
        var _setCriteriaVoteData = function () {
            if ($scope.curCriteriaVotingInfo.voteSubmitted == 0) {
                console.i('setting criteria vote data');
                if (_isSingleBestEnabled())
                    _setCriteriaVote($scope.curCriteriaVotingInfo.subId, $scope.curCriteriaVotes, $scope.curCriteriaVotingInfo.singleBest, $scope.curCriteriaVotingInfo.ballotId);
                else
                    _setCriteriaVote($scope.curCriteriaVotingInfo.subId, $scope.curCriteriaVotes, null, $scope.curCriteriaVotingInfo.ballotId);
            }
            else
                console.i('vote already submitted');
        };
        var _setCriteriaListVoteData = function (criteriaName, number) {
            if ($scope.curCriteriaVotingInfo.voteSubmitted == 0) {
                console.i('setting criteria list vote data');

                // Set the rank number to the curCriteriaVotes
                $scope.curCriteriaVotes[criteriaName] = number;
                if (_isSingleBestEnabled())
                    _setCriteriaVote($scope.curCriteriaVotingInfo.subId, $scope.curCriteriaVotes, $scope.curCriteriaVotingInfo.singleBest, $scope.curCriteriaVotingInfo.ballotId);
                else
                    _setCriteriaVote($scope.curCriteriaVotingInfo.subId, $scope.curCriteriaVotes, null, $scope.curCriteriaVotingInfo.ballotId);
            }
            else
                console.i('vote already submitted');
        };
        var _setCriteriaVote = function (subId, criteriaVotes, singleBest, ballotId) {
            console.i('setting criteria vote for: ' + subId);

            fingerprintPromise.then(function (fingerprint) {
                votingDataService.setCriteriaVote(subId, criteriaVotes, singleBest, fingerprint, ballotId).then(function (results) {
                    $scope.refresh('set');
                },
                    function (error) {
                        console.error('error setting vote');
                    });
            });
        };
        var _moveVoteUp = function (voteId) {
            _moveVote(voteId, 'up');
        };
        var _moveVoteDown = function (voteId) {
            _moveVote(voteId, 'down');
        };
        function _moveVoteUpById(voteId, ballotId) {
            _moveVoteById(voteId, 'up', ballotId);
        };
        function _moveVoteDownById(voteId, ballotId) {
            _moveVoteById(voteId, 'down', ballotId);
        };
        /**
        * @param {string} direction 'up' OR 'down'
        */
        function _moveVote(voteId, direction, ballotId) {
            var voteToMoveIndex = $.map($scope.votes, function (v) { return (v.voteId); }).indexOf(voteId);
            var voteToSwitchWithIndex = 'up' ? voteToMoveIndex - 1 : voteToMoveIndex + 1;

            var voteToMove = $scope.votes[voteToMoveIndex];
            var voteToSwitchWith = $scope.votes[voteToSwitchWithIndex];

            var data = [
                { SubmissionId: voteToMove.submissionId, SortOrder: voteToMove.sortOrder, BallotId: ballotId },
                { SubmissionId: voteToSwitchWith.submissionId, SortOrder: voteToSwitchWith.sortOrder, BallotId: ballotId }
            ];

            votingDataService.swapVotes(data).then(function (results) {
                var key = direction == 'up' ? 'moveup' : 'movedown';
                $scope.refresh(key);
            });
        }
        /**
        * @param {string} direction 'up' OR 'down'
        */
        function _moveVoteById(voteId, direction, ballotId) {
            var voteToMoveIndex = $.map($scope.votes, function (v) { return (v.voteId); }).indexOf(voteId);
            var voteToSwitchWithIndex = direction == 'up' ? voteToMoveIndex - 1 : voteToMoveIndex + 1;

            var voteToMove = $scope.votes[voteToMoveIndex];
            var voteToSwitchWith = $scope.votes[voteToSwitchWithIndex];

            var data = {
                VoteId1: voteToMove.voteId,
                VoteId2: voteToSwitchWith.voteId,
                BallotId: ballotId
            };

            votingDataService.swapVotesById(data).then(function (results) {
                var key = direction == 'up' ? 'moveup' : 'movedown';
                $scope.refresh(key);
            });
        }
        var _submitVotes = function (catId) {
            var deferred = $q.defer();

            votingDataService.submitVotes(catId).then(function (results) {
                $scope.refresh('submit');
                deferred.resolve();
            },
                function (error) {
                    deferred.reject(error.data.exceptionMessage);
                });

            return deferred.promise;
        };

        function _getCurrentBallotId() {
            return $scope.curCriteriaVotingInfo.ballotId;
        }

        function _submitVotesByRoundIds(roundIds) {
            var rounds = [];
            for (var i = 0; i < roundIds.length; i++) {
                rounds.push({ id: roundIds[i] });
            }
            var promise = votingDataService.submitVotesByRoundIds(rounds);
            _handeVoteSubmitting(promise);
            return promise;
        }

        function _submitVotesByRoundId(roundId) {
            var promise = votingDataService.submitVotesByRoundId(roundId);
            _handeVoteSubmitting(promise);
            return promise;
        }

        function _submitVotesByBallotId(roundId) {
            var promise = votingDataService.submitVotesByBallotId(roundId);
            _handeVoteSubmitting(promise);
            return promise;
        }

        function _handeVoteSubmitting(promise) {
            promise.then(function (response) {
                if ($rootScope.blockSiteAccessAfterSubmittingVotes === false) {
                    $scope.refresh('submit');
                }
                return response;
            }).catch(function (response) {
                var message = "Failed to submit votes. Please contact support.";

                if (response.status == 400 &&
                    response.data &&
                    response.data.message == 'CATEGORIES_INCOMPLETE') {
                    message = 'You cannot submit because some of your categories are incomplete.';
                }

                $.awards.alert({
                    title: "Error",
                    message: message,
                    okText: "OK"
                });
            });
        }

        var _submitCriteriaVotes = function (catId) {
            var message = "";
            if (typeof judgeRulesService.getCriteriaVoteConfirmationMessage == "function")
                message = judgeRulesService.getCriteriaVoteConfirmationMessage();

            if (message != "") {
                $.awards.confirm({
                    title: "Submit Category",
                    message: message,
                    okFunction: function () {
                        _submitVotes(catId);
                    },
                    okText: "OK",
                    cancelText: "Cancel",
                    headerCssClass: "bg-success"
                });
            }
        };
        var _submitCriteriaVote = function (voteId) {
            console.i('submit vote for voteId: ' + voteId);
            votingDataService.submitVote(voteId).then(function (results) {
                $scope.refresh('submit');
            },
                function (error) {
                    console.error('error submitting criteria vote');
                });
        };
        var _unsubmitCriteriaVote = function (voteId) {
            console.i('unsubmitting vote for voteId: ' + voteId);
            votingDataService.unsubmitVote(voteId).then(function (results) {
                $scope.refresh('submit');
            },
                function (error) {
                    console.error('error un-submitting criteria vote');
                });
        };

        var _setSingleBest = function () {
            $scope.curCriteriaVotingInfo.singleBest = 1;
            $scope.setCriteriaVoteData();
        };
        var _undoSingleBest = function () {
            $scope.curCriteriaVotingInfo.singleBest = 0;
            $scope.setCriteriaVoteData();
        };

        var _setConflictOfInterest = function (roundId, submissionId, contactId) {
            return $http.post(ngAuthSettings.apiServiceBaseUri + "/vote/setConflictOfInterest/1", { roundId: roundId, submissionId: submissionId, contactId: contactId });
        };
        $scope.init = _init;
        $scope.getVoteTemplatePath = _getVoteTemplatePath;
        $scope.refresh = _refresh;
        $scope.isCategorySubmitted = _isCategorySubmitted;
        $scope.inVotesBySubmissionId = _inVotesBySubmissionId;
        $scope.isCriteriaVoting = _isCriteriaVoting;
        $scope.isSingleBestEnabled = _isSingleBestEnabled;
        $scope.getCriteriaListNumber = _getCriteriaListNumber;
        $scope.getCriteriaNumericLabel = _getCriteriaNumericLabel;
        $scope.checkSelectedCriteriaListVote = _checkSelectedCriteriaListVote;
        $scope.canVote = _canVote;
        $scope.canMakeWriteIn = _canMakeWriteIn;
        $scope.canVoteBySubmissionId = _canVoteBySubmissionId;
        $scope.canDeleteVote = _canDeleteVote;
        $scope.showSubmitVotes = _showSubmitVotes;
        $scope.showCriteriaSubmitVotes = _showCriteriaSubmitVotes;
        $scope.showVoteUp = _showVoteUp;
        $scope.showVoteDown = _showVoteDown;
        $scope.showEmptyRowUIFix = _showEmptyRowUIFix;
        $scope.resetCriteriaVotePanel = _resetCriteriaVotePanel;
        $scope.showCriteriaVoteDetails = _showCriteriaVoteDetails;
        $scope.getVotes = _getVotes;
        $scope.setVote = _setVote;
        $scope.setUnrankedVote = _setUnrankedVote;
        $scope.setCriteriaVote = _setCriteriaVote;
        $scope.setCriteriaVoteData = _setCriteriaVoteData;
        $scope.setWriteInVote = _setWriteInVote;
        $scope.setCriteriaListVoteData = _setCriteriaListVoteData;
        $scope.deleteVotes = _deleteVotes;
        $scope.deleteVotesByCategoryId = _deleteVotesByCategoryId;
        $scope.deleteVote = _deleteVote;
        $scope.deleteVoteBySubmissionId = _deleteVoteBySubmissionId;
        $scope.submitVotes = _submitVotes;
        $scope.submitVotesByRoundIds = _submitVotesByRoundIds;
        $scope.submitVotesByRoundId = _submitVotesByRoundId;
        $scope.submitVotesByBallotId = _submitVotesByBallotId;
        $scope.submitCriteriaVotes = _submitCriteriaVotes;
        $scope.submitCriteriaVote = _submitCriteriaVote;
        $scope.unsubmitCriteriaVote = _unsubmitCriteriaVote;
        $scope.moveVoteUp = _moveVoteUp;
        $scope.moveVoteDown = _moveVoteDown;
        $scope.moveVoteUpById = _moveVoteUpById;
        $scope.moveVoteDownById = _moveVoteDownById;
        $scope.setSingleBest = _setSingleBest;
        $scope.undoSingleBest = _undoSingleBest;
        $scope.setConflictOfInterest = _setConflictOfInterest;
        $scope.isOrderedVoting = _isOrderedVoting;
        $scope.hasWriteIns = _hasWriteIns;
        $scope.getCurrentVoteTypeConfiguration = _getCurrentVoteTypeConfiguration;
        $scope.getVoteDisplayInfo = _getVoteDisplayInfo;
        $scope.getCurrentBallotId = _getCurrentBallotId;

        return $scope;
    }]);