/*
 * Loader:
 * Reads GM result reports written out by results.py, and imports
 * them into $scope.extraColumnHeaders and $scope.imagePairs .
 */
var Loader = angular.module(
    'Loader',
    ['ConstantsModule']
);

Loader.directive(
  'resultsUpdatedCallbackDirective',
  ['$timeout',
   function($timeout) {
     return function(scope, element, attrs) {
       if (scope.$last) {
         $timeout(function() {
           scope.resultsUpdatedCallback();
         });
       }
     };
   }
  ]
);

// TODO(epoger): Combine ALL of our filtering operations (including
// truncation) into this one filter, so that runs most efficiently?
// (We would have to make sure truncation still took place after
// sorting, though.)
Loader.filter(
  'removeHiddenImagePairs',
  function(constants) {
    return function(unfilteredImagePairs, filterableColumnNames, showingColumnValues,
                    viewingTab) {
      var filteredImagePairs = [];
      for (var i = 0; i < unfilteredImagePairs.length; i++) {
        var imagePair = unfilteredImagePairs[i];
        var extraColumnValues = imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
        var allColumnValuesAreVisible = true;
        // Loop over all columns, and if any of them contain values not found in
        // showingColumnValues[columnName], don't include this imagePair.
        //
        // We use this same filtering mechanism regardless of whether each column
        // has USE_FREEFORM_FILTER set or not; if that flag is set, then we will
        // have already used the freeform text entry block to populate
        // showingColumnValues[columnName].
        for (var j = 0; j < filterableColumnNames.length; j++) {
          var columnName = filterableColumnNames[j];
          var columnValue = extraColumnValues[columnName];
          if (!showingColumnValues[columnName][columnValue]) {
            allColumnValuesAreVisible = false;
            break;
          }
        }
        if (allColumnValuesAreVisible && (viewingTab == imagePair.tab)) {
          filteredImagePairs.push(imagePair);
        }
      }
      return filteredImagePairs;
    };
  }
);

/**
 * Limit the input imagePairs to some max number, and merge identical rows
 * (adjacent rows which have the same (imageA, imageB) pair).
 *
 * @param unfilteredImagePairs imagePairs to filter
 * @param maxPairs maximum number of pairs to output, or <0 for no limit
 * @param mergeIdenticalRows if true, merge identical rows by setting
 *     ROWSPAN>1 on the first merged row, and ROWSPAN=0 for the rest
 */
Loader.filter(
  'mergeAndLimit',
  function(constants) {
    return function(unfilteredImagePairs, maxPairs, mergeIdenticalRows) {
      var numPairs = unfilteredImagePairs.length;
      if ((maxPairs > 0) && (maxPairs < numPairs)) {
        numPairs = maxPairs;
      }
      var filteredImagePairs = [];
      if (!mergeIdenticalRows || (numPairs == 1)) {
        // Take a shortcut if we're not merging identical rows.
        // We still need to set ROWSPAN to 1 for each row, for the HTML viewer.
        for (var i = numPairs-1; i >= 0; i--) {
          var imagePair = unfilteredImagePairs[i];
          imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
          filteredImagePairs[i] = imagePair;
        }
      } else if (numPairs > 1) {
        // General case--there are at least 2 rows, so we may need to merge some.
        // Work from the bottom up, so we can keep a running total of how many
        // rows should be merged, and set ROWSPAN of the top row accordingly.
        var imagePair = unfilteredImagePairs[numPairs-1];
        var nextRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL];
        var nextRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
        imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
        filteredImagePairs[numPairs-1] = imagePair;
        for (var i = numPairs-2; i >= 0; i--) {
          imagePair = unfilteredImagePairs[i];
          var thisRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL];
          var thisRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
          if ((thisRowImageAUrl == nextRowImageAUrl) &&
              (thisRowImageBUrl == nextRowImageBUrl)) {
            imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] =
                filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] + 1;
            filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] = 0;
          } else {
            imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
            nextRowImageAUrl = thisRowImageAUrl;
            nextRowImageBUrl = thisRowImageBUrl;
          }
          filteredImagePairs[i] = imagePair;
        }
      } else {
        // No results.
      }
      return filteredImagePairs;
    };
  }
);


Loader.controller(
  'Loader.Controller',
    function($scope, $http, $filter, $location, $log, $timeout, constants) {
    $scope.readyToDisplay = false;
    $scope.constants = constants;
    $scope.windowTitle = "Loading GM Results...";
    $scope.resultsToLoad = $location.search().resultsToLoad;
    $scope.loadingMessage = "please wait...";

    var currSortAsc = true; 


    /**
     * On initial page load, load a full dictionary of results.
     * Once the dictionary is loaded, unhide the page elements so they can
     * render the data.
     */
    $http.get($scope.resultsToLoad).success(
      function(data, status, header, config) {
        var dataHeader = data[constants.KEY__ROOT__HEADER];
        if (dataHeader[constants.KEY__HEADER__SCHEMA_VERSION] !=
            constants.VALUE__HEADER__SCHEMA_VERSION) {
          $scope.loadingMessage = "ERROR: Got JSON file with schema version "
              + dataHeader[constants.KEY__HEADER__SCHEMA_VERSION]
              + " but expected schema version "
              + constants.VALUE__HEADER__SCHEMA_VERSION;
        } else if (dataHeader[constants.KEY__HEADER__IS_STILL_LOADING]) {
          // Apply the server's requested reload delay to local time,
          // so we will wait the right number of seconds regardless of clock
          // skew between client and server.
          var reloadDelayInSeconds =
              dataHeader[constants.KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE] -
              dataHeader[constants.KEY__HEADER__TIME_UPDATED];
          var timeNow = new Date().getTime();
          var timeToReload = timeNow + reloadDelayInSeconds * 1000;
          $scope.loadingMessage =
              "server is still loading results; will retry at " +
              $scope.localTimeString(timeToReload / 1000);
          $timeout(
              function(){location.reload();},
              timeToReload - timeNow);
        } else {
          $scope.loadingMessage = "processing data, please wait...";

          $scope.header = dataHeader;
          $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADERS];
          $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER];
          $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS];
          $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS];

          // set the default sort column and make it ascending.
          $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES;
          $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF;
          currSortAsc = true;

          $scope.showSubmitAdvancedSettings = false;
          $scope.submitAdvancedSettings = {};
          $scope.submitAdvancedSettings[
              constants.KEY__EXPECTATIONS__REVIEWED] = true;
          $scope.submitAdvancedSettings[
              constants.KEY__EXPECTATIONS__IGNOREFAILURE] = false;
          $scope.submitAdvancedSettings['bug'] = '';

          // Create the list of tabs (lists into which the user can file each
          // test).  This may vary, depending on isEditable.
          $scope.tabs = [
            'Unfiled', 'Hidden'
          ];
          if (dataHeader[constants.KEY__HEADER__IS_EDITABLE]) {
            $scope.tabs = $scope.tabs.concat(
                ['Pending Approval']);
          }
          $scope.defaultTab = $scope.tabs[0];
          $scope.viewingTab = $scope.defaultTab;

          // Track the number of results on each tab.
          $scope.numResultsPerTab = {};
          for (var i = 0; i < $scope.tabs.length; i++) {
            $scope.numResultsPerTab[$scope.tabs[i]] = 0;
          }
          $scope.numResultsPerTab[$scope.defaultTab] = $scope.imagePairs.length;

          // Add index and tab fields to all records.
          for (var i = 0; i < $scope.imagePairs.length; i++) {
            $scope.imagePairs[i].index = i;
            $scope.imagePairs[i].tab = $scope.defaultTab;
          }

          // Arrays within which the user can toggle individual elements.
          $scope.selectedImagePairs = [];

          // Set up filters.
          //
          // filterableColumnNames is a list of all column names we can filter on.
          // allColumnValues[columnName] is a list of all known values
          // for a given column.
          // showingColumnValues[columnName] is a set indicating which values
          // in a given column would cause us to show a row, rather than hiding it.
          //
          // columnStringMatch[columnName] is a string used as a pattern to generate
          // showingColumnValues[columnName] for columns we filter using free-form text.
          // It is ignored for any columns with USE_FREEFORM_FILTER == false.
          $scope.filterableColumnNames = [];
          $scope.allColumnValues = {};
          $scope.showingColumnValues = {};
          $scope.columnStringMatch = {};

          angular.forEach(
            Object.keys($scope.extraColumnHeaders),
            function(columnName) {
              var columnHeader = $scope.extraColumnHeaders[columnName];
              if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]) {
                $scope.filterableColumnNames.push(columnName);
                $scope.allColumnValues[columnName] = $scope.columnSliceOf2DArray(
                    columnHeader[constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS], 0);
                $scope.showingColumnValues[columnName] = {};
                $scope.toggleValuesInSet($scope.allColumnValues[columnName],
                                         $scope.showingColumnValues[columnName]);
                $scope.columnStringMatch[columnName] = "";
              }
            }
          );

          // TODO(epoger): Special handling for RESULT_TYPE column:
          // by default, show only KEY__RESULT_TYPE__FAILED results
          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE] = {};
          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE][
              constants.KEY__RESULT_TYPE__FAILED] = true;

          // Set up mapping for URL parameters.
          // parameter name -> copier object to load/save parameter value
          $scope.queryParameters.map = {
            'resultsToLoad':         $scope.queryParameters.copiers.simple,
            'displayLimitPending':   $scope.queryParameters.copiers.simple,
            'showThumbnailsPending': $scope.queryParameters.copiers.simple,
            'mergeIdenticalRowsPending': $scope.queryParameters.copiers.simple,
            'imageSizePending':      $scope.queryParameters.copiers.simple,
            'sortColumnSubdict':     $scope.queryParameters.copiers.simple,
            'sortColumnKey':         $scope.queryParameters.copiers.simple,
          };
          // Some parameters are handled differently based on whether they USE_FREEFORM_FILTER.
          angular.forEach(
            $scope.filterableColumnNames,
            function(columnName) {
              if ($scope.extraColumnHeaders[columnName]
                  [constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
                $scope.queryParameters.map[columnName] =
                    $scope.queryParameters.copiers.columnStringMatch;
              } else {
                $scope.queryParameters.map[columnName] =
                    $scope.queryParameters.copiers.showingColumnValuesSet;
              }
            }
          );

          // If any defaults were overridden in the URL, get them now.
          $scope.queryParameters.load();

          // Any image URLs which are relative should be relative to the JSON
          // file's source directory; absolute URLs should be left alone.
          var baseUrlKey = constants.KEY__IMAGESETS__FIELD__BASE_URL;
          angular.forEach(
            $scope.imageSets,
            function(imageSet) {
              var baseUrl = imageSet[baseUrlKey];
              if ((baseUrl.substring(0, 1) != '/') &&
                  (baseUrl.indexOf('://') == -1)) {
                imageSet[baseUrlKey] = $scope.resultsToLoad + '/../' + baseUrl;
              }
            }
          );

          $scope.readyToDisplay = true;
          $scope.updateResults();
          $scope.loadingMessage = "";
          $scope.windowTitle = "Current GM Results";

          $timeout( function() {
            make_results_header_sticky();
          });
        }
      }
    ).error(
      function(data, status, header, config) {
        $scope.loadingMessage = "FAILED to load.";
        $scope.windowTitle = "Failed to Load GM Results";
      }
    );


    //
    // Select/Clear/Toggle all tests.
    //

    /**
     * Select all currently showing tests.
     */
    $scope.selectAllImagePairs = function() {
      var numImagePairsShowing = $scope.limitedImagePairs.length;
      for (var i = 0; i < numImagePairsShowing; i++) {
        var index = $scope.limitedImagePairs[i].index;
        if (!$scope.isValueInArray(index, $scope.selectedImagePairs)) {
          $scope.toggleValueInArray(index, $scope.selectedImagePairs);
        }
      }
    };

    /**
     * Deselect all currently showing tests.
     */
    $scope.clearAllImagePairs = function() {
      var numImagePairsShowing = $scope.limitedImagePairs.length;
      for (var i = 0; i < numImagePairsShowing; i++) {
        var index = $scope.limitedImagePairs[i].index;
        if ($scope.isValueInArray(index, $scope.selectedImagePairs)) {
          $scope.toggleValueInArray(index, $scope.selectedImagePairs);
        }
      }
    };

    /**
     * Toggle selection of all currently showing tests.
     */
    $scope.toggleAllImagePairs = function() {
      var numImagePairsShowing = $scope.limitedImagePairs.length;
      for (var i = 0; i < numImagePairsShowing; i++) {
        var index = $scope.limitedImagePairs[i].index;
        $scope.toggleValueInArray(index, $scope.selectedImagePairs);
      }
    };

    /**
     * Toggle selection state of a subset of the currently showing tests.
     *
     * @param startIndex index within $scope.limitedImagePairs of the first
     *     test to toggle selection state of
     * @param num number of tests (in a contiguous block) to toggle
     */
    $scope.toggleSomeImagePairs = function(startIndex, num) {
      var numImagePairsShowing = $scope.limitedImagePairs.length;
      for (var i = startIndex; i < startIndex + num; i++) {
        var index = $scope.limitedImagePairs[i].index;
        $scope.toggleValueInArray(index, $scope.selectedImagePairs);
      }
    };


    //
    // Tab operations.
    //

    /**
     * Change the selected tab.
     *
     * @param tab (string): name of the tab to select
     */
    $scope.setViewingTab = function(tab) {
      $scope.viewingTab = tab;
      $scope.updateResults();
    };

    /**
     * Move the imagePairs in $scope.selectedImagePairs to a different tab,
     * and then clear $scope.selectedImagePairs.
     *
     * @param newTab (string): name of the tab to move the tests to
     */
    $scope.moveSelectedImagePairsToTab = function(newTab) {
      $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab);
      $scope.selectedImagePairs = [];
      $scope.updateResults();
    };

    /**
     * Move a subset of $scope.imagePairs to a different tab.
     *
     * @param imagePairIndices (array of ints): indices into $scope.imagePairs
     *        indicating which test results to move
     * @param newTab (string): name of the tab to move the tests to
     */
    $scope.moveImagePairsToTab = function(imagePairIndices, newTab) {
      var imagePairIndex;
      var numImagePairs = imagePairIndices.length;
      for (var i = 0; i < numImagePairs; i++) {
        imagePairIndex = imagePairIndices[i];
        $scope.numResultsPerTab[$scope.imagePairs[imagePairIndex].tab]--;
        $scope.imagePairs[imagePairIndex].tab = newTab;
      }
      $scope.numResultsPerTab[newTab] += numImagePairs;
    };


    //
    // $scope.queryParameters:
    // Transfer parameter values between $scope and the URL query string.
    //
    $scope.queryParameters = {};

    // load and save functions for parameters of each type
    // (load a parameter value into $scope from nameValuePairs,
    //  save a parameter value from $scope into nameValuePairs)
    $scope.queryParameters.copiers = {
      'simple': {
        'load': function(nameValuePairs, name) {
          var value = nameValuePairs[name];
          if (value) {
            $scope[name] = value;
          }
        },
        'save': function(nameValuePairs, name) {
          nameValuePairs[name] = $scope[name];
        }
      },

      'columnStringMatch': {
        'load': function(nameValuePairs, name) {
          var value = nameValuePairs[name];
          if (value) {
            $scope.columnStringMatch[name] = value;
          }
        },
        'save': function(nameValuePairs, name) {
          nameValuePairs[name] = $scope.columnStringMatch[name];
        }
      },

      'showingColumnValuesSet': {
        'load': function(nameValuePairs, name) {
          var value = nameValuePairs[name];
          if (value) {
            var valueArray = value.split(',');
            $scope.showingColumnValues[name] = {};
            $scope.toggleValuesInSet(valueArray, $scope.showingColumnValues[name]);
          }
        },
        'save': function(nameValuePairs, name) {
          nameValuePairs[name] = Object.keys($scope.showingColumnValues[name]).join(',');
        }
      },

    };

    // Loads all parameters into $scope from the URL query string;
    // any which are not found within the URL will keep their current value.
    $scope.queryParameters.load = function() {
      var nameValuePairs = $location.search();

      // If urlSchemaVersion is not specified, we assume the current version.
      var urlSchemaVersion = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
      if (constants.URL_KEY__SCHEMA_VERSION in nameValuePairs) {
        urlSchemaVersion = nameValuePairs[constants.URL_KEY__SCHEMA_VERSION];
      } else if ('hiddenResultTypes' in nameValuePairs) {
        // The combination of:
        // - absence of an explicit urlSchemaVersion, and
        // - presence of the old 'hiddenResultTypes' field
        // tells us that the URL is from the original urlSchemaVersion.
        // See https://codereview.chromium.org/367173002/
        urlSchemaVersion = 0;
      }
      $scope.urlSchemaVersionLoaded = urlSchemaVersion;

      if (urlSchemaVersion != constants.URL_VALUE__SCHEMA_VERSION__CURRENT) {
        nameValuePairs = $scope.upconvertUrlNameValuePairs(nameValuePairs, urlSchemaVersion);
      }
      angular.forEach($scope.queryParameters.map,
                      function(copier, paramName) {
                        copier.load(nameValuePairs, paramName);
                      }
                     );
    };

    // Saves all parameters from $scope into the URL query string.
    $scope.queryParameters.save = function() {
      var nameValuePairs = {};
      nameValuePairs[constants.URL_KEY__SCHEMA_VERSION] = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
      angular.forEach($scope.queryParameters.map,
                      function(copier, paramName) {
                        copier.save(nameValuePairs, paramName);
                      }
                     );
      $location.search(nameValuePairs);
    };

    /**
     * Converts URL name/value pairs that were stored by a previous urlSchemaVersion
     * to the currently needed format.
     *
     * @param oldNValuePairs name/value pairs found in the loaded URL
     * @param oldUrlSchemaVersion which version of the schema was used to generate that URL
     *
     * @returns nameValuePairs as needed by the current URL parser
     */
    $scope.upconvertUrlNameValuePairs = function(oldNameValuePairs, oldUrlSchemaVersion) {
      var newNameValuePairs = {};
      angular.forEach(oldNameValuePairs,
                      function(value, name) {
                        if (oldUrlSchemaVersion < 1) {
                          if ('hiddenConfigs' == name) {
                            name = 'config';
                            var valueSet = {};
                            $scope.toggleValuesInSet(value.split(','), valueSet);
                            $scope.toggleValuesInSet(
                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__CONFIG],
                                valueSet);
                            value = Object.keys(valueSet).join(',');
                          } else if ('hiddenResultTypes' == name) {
                            name = 'resultType';
                            var valueSet = {};
                            $scope.toggleValuesInSet(value.split(','), valueSet);
                            $scope.toggleValuesInSet(
                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE],
                                valueSet);
                            value = Object.keys(valueSet).join(',');
                          }
                        }

                        newNameValuePairs[name] = value;
                      }
                     );
      return newNameValuePairs;
    }


    //
    // updateResults() and friends.
    //

    /**
     * Set $scope.areUpdatesPending (to enable/disable the Update Results
     * button).
     *
     * TODO(epoger): We could reduce the amount of code by just setting the
     * variable directly (from, e.g., a button's ng-click handler).  But when
     * I tried that, the HTML elements depending on the variable did not get
     * updated.
     * It turns out that this is due to variable scoping within an ng-repeat
     * element; see http://stackoverflow.com/questions/15388344/behavior-of-assignment-expression-invoked-by-ng-click-within-ng-repeat
     *
     * @param val boolean value to set $scope.areUpdatesPending to
     */
    $scope.setUpdatesPending = function(val) {
      $scope.areUpdatesPending = val;
    }

    /**
     * Update the displayed results, based on filters/settings,
     * and call $scope.queryParameters.save() so that the new filter results
     * can be bookmarked.
     */
    $scope.updateResults = function() {
      $scope.renderStartTime = window.performance.now();
      $log.debug("renderStartTime: " + $scope.renderStartTime);
      $scope.displayLimit = $scope.displayLimitPending;
      $scope.mergeIdenticalRows = $scope.mergeIdenticalRowsPending;

      // For each USE_FREEFORM_FILTER column, populate showingColumnValues.
      // This is more efficient than applying the freeform filter within the
      // tight loop in removeHiddenImagePairs.
      angular.forEach(
        $scope.filterableColumnNames,
        function(columnName) {
          var columnHeader = $scope.extraColumnHeaders[columnName];
          if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
            var columnStringMatch = $scope.columnStringMatch[columnName];
            var showingColumnValues = {};
            angular.forEach(
              $scope.allColumnValues[columnName],
              function(columnValue) {
                if (-1 != columnValue.indexOf(columnStringMatch)) {
                  showingColumnValues[columnValue] = true;
                }
              }
            );
            $scope.showingColumnValues[columnName] = showingColumnValues;
          }
        }
      );

      // TODO(epoger): Every time we apply a filter, AngularJS creates
      // another copy of the array.  Is there a way we can filter out
      // the imagePairs as they are displayed, rather than storing multiple
      // array copies?  (For better performance.)
      if ($scope.viewingTab == $scope.defaultTab) {
        var doReverse = !currSortAsc;

        $scope.filteredImagePairs =
            $filter("orderBy")(
                $filter("removeHiddenImagePairs")(
                    $scope.imagePairs,
                    $scope.filterableColumnNames,
                    $scope.showingColumnValues,
                    $scope.viewingTab
                ),
                // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
                $scope.getSortColumnValue,
                doReverse);
        $scope.limitedImagePairs = $filter("mergeAndLimit")(
            $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdenticalRows);
      } else {
        $scope.filteredImagePairs =
            $filter("orderBy")(
                $filter("filter")(
                    $scope.imagePairs,
                    {tab: $scope.viewingTab},
                    true
                ),
                // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
                $scope.getSortColumnValue);
        $scope.limitedImagePairs = $filter("mergeAndLimit")(
            $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows);
      }
      $scope.showThumbnails = $scope.showThumbnailsPending;
      $scope.imageSize = $scope.imageSizePending;
      $scope.setUpdatesPending(false);
      $scope.queryParameters.save();
    }

    /**
     * This function is called when the results have been completely rendered
     * after updateResults().
     */
    $scope.resultsUpdatedCallback = function() {
      $scope.renderEndTime = window.performance.now();
      $log.debug("renderEndTime: " + $scope.renderEndTime);
    };

    /**
     * Re-sort the displayed results.
     *
     * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary
     *     the sort column key is within, or 'none' if the sort column
     *     key is one of KEY__IMAGEPAIRS__*
     * @param key (string): sort by value associated with this key in subdict
     */
    $scope.sortResultsBy = function(subdict, key) {
      // if we are already sorting by this column then toggle between asc/desc
      if ((subdict === $scope.sortColumnSubdict) && ($scope.sortColumnKey === key)) {
        currSortAsc = !currSortAsc;
      } else {
        $scope.sortColumnSubdict = subdict;
        $scope.sortColumnKey = key;
        currSortAsc = true; 
      }
      $scope.updateResults();
    };

    /**
     * Returns ASC or DESC (from constants) if currently the data
     * is sorted by the provided column. 
     *
     * @param colName: name of the column for which we need to get the class.
     */

    $scope.sortedByColumnsCls = function (colName) {
      if ($scope.sortColumnKey !== colName) {
        return '';
      }

      var result = (currSortAsc) ? constants.ASC : constants.DESC;
      console.log("sort class:", result);
      return result;
    };

    /**
     * For a particular ImagePair, return the value of the column we are
     * sorting on (according to $scope.sortColumnSubdict and
     * $scope.sortColumnKey).
     *
     * @param imagePair: imagePair to get a column value out of.
     */
    $scope.getSortColumnValue = function(imagePair) {
      if ($scope.sortColumnSubdict in imagePair) {
        return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey];
      } else if ($scope.sortColumnKey in imagePair) {
        return imagePair[$scope.sortColumnKey];
      } else {
        return undefined;
      }
    };

    /**
     * For a particular ImagePair, return the value we use for the
     * second-order sort (tiebreaker when multiple rows have
     * the same getSortColumnValue()).
     *
     * We join the imageA and imageB urls for this value, so that we merge
     * adjacent rows as much as possible.
     *
     * @param imagePair: imagePair to get a column value out of.
     */
    $scope.getSecondOrderSortValue = function(imagePair) {
      return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
    };

    /**
     * Set $scope.columnStringMatch[name] = value, and update results.
     *
     * @param name
     * @param value
     */
    $scope.setColumnStringMatch = function(name, value) {
      $scope.columnStringMatch[name] = value;
      $scope.updateResults();
    };

    /**
     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
     * so that ONLY entries with this columnValue are showing, and update the visible results.
     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
     *
     * @param columnName
     * @param columnValue
     */
    $scope.showOnlyColumnValue = function(columnName, columnValue) {
      $scope.columnStringMatch[columnName] = columnValue;
      $scope.showingColumnValues[columnName] = {};
      $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName]);
      $scope.updateResults();
    };

    /**
     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
     * so that ALL entries are showing, and update the visible results.
     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
     *
     * @param columnName
     */
    $scope.showAllColumnValues = function(columnName) {
      $scope.columnStringMatch[columnName] = "";
      $scope.showingColumnValues[columnName] = {};
      $scope.toggleValuesInSet($scope.allColumnValues[columnName],
                               $scope.showingColumnValues[columnName]);
      $scope.updateResults();
    };


    //
    // Operations for sending info back to the server.
    //

    /**
     * Tell the server that the actual results of these particular tests
     * are acceptable.
     *
     * TODO(epoger): This assumes that the original expectations are in
     * imageSetA, and the actuals are in imageSetB.
     *
     * @param imagePairsSubset an array of test results, most likely a subset of
     *        $scope.imagePairs (perhaps with some modifications)
     */
    $scope.submitApprovals = function(imagePairsSubset) {
      $scope.submitPending = true;

      // Convert bug text field to null or 1-item array.
      var bugs = null;
      var bugNumber = parseInt($scope.submitAdvancedSettings['bug']);
      if (!isNaN(bugNumber)) {
        bugs = [bugNumber];
      }

      // TODO(epoger): This is a suboptimal way to prevent users from
      // rebaselining failures in alternative renderModes, but it does work.
      // For a better solution, see
      // https://code.google.com/p/skia/issues/detail?id=1748 ('gm: add new
      // result type, RenderModeMismatch')
      var encounteredComparisonConfig = false;

      var updatedExpectations = [];
      for (var i = 0; i < imagePairsSubset.length; i++) {
        var imagePair = imagePairsSubset[i];
        var updatedExpectation = {};
        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] =
            imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS];
        updatedExpectation[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS] =
            imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
        // IMAGE_B_URL contains the actual image (which is now the expectation)
        updatedExpectation[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] =
            imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
        if (0 == updatedExpectation[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS]
                                   [constants.KEY__EXTRACOLUMNS__CONFIG]
                                   .indexOf('comparison-')) {
          encounteredComparisonConfig = true;
        }

        // Advanced settings...
        if (null == updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]) {
          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] = {};
        }
        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                          [constants.KEY__EXPECTATIONS__REVIEWED] =
            $scope.submitAdvancedSettings[
                constants.KEY__EXPECTATIONS__REVIEWED];
        if (true == $scope.submitAdvancedSettings[
            constants.KEY__EXPECTATIONS__IGNOREFAILURE]) {
          // if it's false, don't send it at all (just keep the default)
          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                            [constants.KEY__EXPECTATIONS__IGNOREFAILURE] = true;
        }
        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                          [constants.KEY__EXPECTATIONS__BUGS] = bugs;

        updatedExpectations.push(updatedExpectation);
      }
      if (encounteredComparisonConfig) {
        alert("Approval failed -- you cannot approve results with config " +
            "type comparison-*");
        $scope.submitPending = false;
        return;
      }
      var modificationData = {};
      modificationData[constants.KEY__EDITS__MODIFICATIONS] =
          updatedExpectations;
      modificationData[constants.KEY__EDITS__OLD_RESULTS_HASH] =
          $scope.header[constants.KEY__HEADER__DATAHASH];
      modificationData[constants.KEY__EDITS__OLD_RESULTS_TYPE] =
          $scope.header[constants.KEY__HEADER__TYPE];
      $http({
        method: "POST",
        url: "/edits",
        data: modificationData
      }).success(function(data, status, headers, config) {
        var imagePairIndicesToMove = [];
        for (var i = 0; i < imagePairsSubset.length; i++) {
          imagePairIndicesToMove.push(imagePairsSubset[i].index);
        }
        $scope.moveImagePairsToTab(imagePairIndicesToMove,
                                   "HackToMakeSureThisImagePairDisappears");
        $scope.updateResults();
        alert("New baselines submitted successfully!\n\n" +
            "You still need to commit the updated expectations files on " +
            "the server side to the Skia repo.\n\n" +
            "When you click OK, your web UI will reload; after that " +
            "completes, you will see the updated data (once the server has " +
            "finished loading the update results into memory!) and you can " +
            "submit more baselines if you want.");
        // I don't know why, but if I just call reload() here it doesn't work.
        // Making a timer call it fixes the problem.
        $timeout(function(){location.reload();}, 1);
      }).error(function(data, status, headers, config) {
        alert("There was an error submitting your baselines.\n\n" +
            "Please see server-side log for details.");
        $scope.submitPending = false;
      });
    };


    //
    // Operations we use to mimic Set semantics, in such a way that
    // checking for presence within the Set is as fast as possible.
    // But getting a list of all values within the Set is not necessarily
    // possible.
    // TODO(epoger): move into a separate .js file?
    //

    /**
     * Returns the number of values present within set "set".
     *
     * @param set an Object which we use to mimic set semantics
     */
    $scope.setSize = function(set) {
      return Object.keys(set).length;
    };

    /**
     * Returns true if value "value" is present within set "set".
     *
     * @param value a value of any type
     * @param set an Object which we use to mimic set semantics
     *        (this should make isValueInSet faster than if we used an Array)
     */
    $scope.isValueInSet = function(value, set) {
      return (true == set[value]);
    };

    /**
     * If value "value" is already in set "set", remove it; otherwise, add it.
     *
     * @param value a value of any type
     * @param set an Object which we use to mimic set semantics
     */
    $scope.toggleValueInSet = function(value, set) {
      if (true == set[value]) {
        delete set[value];
      } else {
        set[value] = true;
      }
    };

    /**
     * For each value in valueArray, call toggleValueInSet(value, set).
     *
     * @param valueArray
     * @param set
     */
    $scope.toggleValuesInSet = function(valueArray, set) {
      var arrayLength = valueArray.length;
      for (var i = 0; i < arrayLength; i++) {
        $scope.toggleValueInSet(valueArray[i], set);
      }
    };


    //
    // Array operations; similar to our Set operations, but operate on a
    // Javascript Array so we *can* easily get a list of all values in the Set.
    // TODO(epoger): move into a separate .js file?
    //

    /**
     * Returns true if value "value" is present within array "array".
     *
     * @param value a value of any type
     * @param array a Javascript Array
     */
    $scope.isValueInArray = function(value, array) {
      return (-1 != array.indexOf(value));
    };

    /**
     * If value "value" is already in array "array", remove it; otherwise,
     * add it.
     *
     * @param value a value of any type
     * @param array a Javascript Array
     */
    $scope.toggleValueInArray = function(value, array) {
      var i = array.indexOf(value);
      if (-1 == i) {
        array.push(value);
      } else {
        array.splice(i, 1);
      }
    };


    //
    // Miscellaneous utility functions.
    // TODO(epoger): move into a separate .js file?
    //

    /**
     * Returns a single "column slice" of a 2D array.
     *
     * For example, if array is:
     * [[A0, A1],
     *  [B0, B1],
     *  [C0, C1]]
     * and index is 0, this this will return:
     * [A0, B0, C0]
     *
     * @param array a Javascript Array
     * @param column (numeric): index within each row array
     */
    $scope.columnSliceOf2DArray = function(array, column) {
      var slice = [];
      var numRows = array.length;
      for (var row = 0; row < numRows; row++) {
        slice.push(array[row][column]);
      }
      return slice;
    };

    /**
     * Returns a human-readable (in local time zone) time string for a
     * particular moment in time.
     *
     * @param secondsPastEpoch (numeric): seconds past epoch in UTC
     */
    $scope.localTimeString = function(secondsPastEpoch) {
      var d = new Date(secondsPastEpoch * 1000);
      return d.toString();
    };

    /**
     * Returns a hex color string (such as "#aabbcc") for the given RGB values.
     *
     * @param r (numeric): red channel value, 0-255
     * @param g (numeric): green channel value, 0-255
     * @param b (numeric): blue channel value, 0-255
     */
    $scope.hexColorString = function(r, g, b) {
      var rString = r.toString(16);
      if (r < 16) {
        rString = "0" + rString;
      }
      var gString = g.toString(16);
      if (g < 16) {
        gString = "0" + gString;
      }
      var bString = b.toString(16);
      if (b < 16) {
        bString = "0" + bString;
      }
      return '#' + rString + gString + bString;
    };

    /**
     * Returns a hex color string (such as "#aabbcc") for the given brightness.
     *
     * @param brightnessString (string): 0-255, 0 is completely black
     *
     * TODO(epoger): It might be nice to tint the color when it's not completely
     * black or completely white.
     */
    $scope.brightnessStringToHexColor = function(brightnessString) {
      var v = parseInt(brightnessString);
      return $scope.hexColorString(v, v, v);
    };

  }
);
