
/**
 * The application header bar.
 */
angular.module('quay').directive('headerBar', function () {
  var number = 0;
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/header-bar.html',
    replace: false,
    transclude: false,
    restrict: 'C',
    scope: {
    },
    controller: function($rootScope, $scope, $element, $location, $timeout, hotkeys, UserService,
          PlanService, ApiService, NotificationService, Config, CreateService, Features) {
      var hotkeysAdded = false;
      var userUpdated = function(cUser) {
        $scope.searchingAllowed = Features.ANONYMOUS_ACCESS || !cUser.anonymous;

        if (hotkeysAdded) { return; }
        hotkeysAdded = true;

        // Register hotkeys.
        if ($scope.searchingAllowed) {
          hotkeys.add({
            combo: '/',
            description: 'Show search',
            callback: function(e) {
              e.preventDefault();
              e.stopPropagation();
              $scope.toggleSearch();
            }
          });
        }

        if (!cUser.anonymous) {
          hotkeys.add({
            combo: 'alt+c',
            description: 'Create new repository',
            callback: function(e) {
              e.preventDefault();
              e.stopPropagation();
              $location.url('/new');
            }
          });
        }
      };

      $scope.notificationService = NotificationService;
      $scope.searchingAllowed = false;
      $scope.searchVisible = false;
      $scope.currentSearchQuery = null;
      $scope.searchResultState = null;
      $scope.showBuildDialogCounter = 0;

      // Monitor any user changes and place the current user into the scope.
      UserService.updateUserIn($scope, userUpdated);

      $scope.currentPageContext = {};

      $rootScope.$watch('currentPage.scope.viewuser', function(u) {
        $scope.currentPageContext['viewuser'] = u;
      });

      $rootScope.$watch('currentPage.scope.organization', function(o) {
        $scope.currentPageContext['organization'] = o;
      });

      $rootScope.$watch('currentPage.scope.repository', function(r) {
        $scope.currentPageContext['repository'] = r;
      });

      var conductSearch = function(query) {
        if (!query) { $scope.searchResultState = null; return; }

        $scope.searchResultState = {
          'state': 'loading'
        };

        var params = {
          'query': query
        };

        ApiService.conductSearch(null, params).then(function(resp) {
          if (!$scope.searchVisible || query != $scope.currentSearchQuery) { return; }

          $scope.searchResultState = {
            'state': resp.results.length ? 'results' : 'no-results',
            'results': resp.results,
            'current': resp.results.length ? 0 : -1
          };
        }, function(resp) {
          $scope.searchResultState = null;
        }, /* background */ true);
      };

      $scope.$watch('currentSearchQuery', conductSearch);

      $scope.signout = function() {
        ApiService.logout().then(function() {
          UserService.load();
          $location.path('/');
        });
      };

      $scope.appLinkTarget = function() {
        if ($scope._appLinkTarget) {
          return $scope._appLinkTarget;
        }

        if ($("div[ng-view]").length === 0) {
            return $scope._appLinkTarget = "_self";
        }

        return $scope._appLinkTarget = "";
      };

      $scope.getEnterpriseLogo = function() {
        if (!Config.ENTERPRISE_LOGO_URL) {
          return '/static/img/quay-logo.png';
        }

        return Config.ENTERPRISE_LOGO_URL;
      };

      $scope.toggleSearch = function() {
        $scope.searchVisible = !$scope.searchVisible;
        if ($scope.searchVisible) {
          $('#search-box-input').focus();
          if ($scope.currentSearchQuery) {
            conductSearch($scope.currentSearchQuery);
          }
        } else {
          $('#search-box-input').blur()
          $scope.searchResultState = null;
        }
      };

      $scope.getSearchBoxClasses = function(searchVisible, searchResultState) {
        var classes = searchVisible ? 'search-visible ' : '';
        if (searchResultState) {
          classes += 'results-visible';
        }
        return classes;
      };

      $scope.handleSearchKeyDown = function(e) {
        if (e.keyCode == 27) {
          $scope.toggleSearch();
          return;
        }

        var state = $scope.searchResultState;
        if (!state || !state['results']) { return; }

        if (e.keyCode == 40) {
          state['current']++;
          e.preventDefault();
        } else if (e.keyCode == 38) {
          state['current']--;
          e.preventDefault();
        } else if (e.keyCode == 13) {
          var current = state['current'];
          if (current >= 0 && current < state['results'].length) {
            $scope.showResult(state['results'][current]);
          }
          e.preventDefault();
        }

        if (state['current'] < -1) {
          state['current'] = state['results'].length - 1;
        } else if (state['current'] >= state['results'].length) {
          state['current'] = 0;
        }
      };

      $scope.showResult = function(result) {
        $scope.toggleSearch();
        $timeout(function() {
          $scope.currentSearchQuery = '';
          $location.url(result['href'])
        }, 500);
      };

      $scope.setCurrentResult = function(result) {
        if (!$scope.searchResultState) { return; }
        $scope.searchResultState['current'] = result;
      };

      $scope.getNamespace = function(context) {
        if (!context) { return null; }

        if (context.repository && context.repository.namespace) {
          return context.repository.namespace;
        }

        if (context.organization && context.organization.name) {
          return context.organization.name;
        }

        if (context.viewuser && context.viewuser.username) {
          return context.viewuser.username;
        }

        return null;
      };

      $scope.canAdmin = function(namespace) {
        if (!namespace) { return false; }
        return UserService.isNamespaceAdmin(namespace);
      };

      $scope.isOrganization = function(namespace) {
        if (!namespace) { return false; }
        return UserService.isOrganization(namespace);
      };

      $scope.startBuild = function(context) {
        $scope.showBuildDialogCounter++;
      };

      $scope.handleBuildStarted = function(build, context) {
        $location.url('/repository/' + context.repository.namespace + '/' + context.repository.name + '/build/' + build.id);
      };

      $scope.createRobot = function(context) {
        var namespace = $scope.getNamespace(context);
        CreateService.askCreateRobot(namespace, function(created) {
          if (UserService.isOrganization(namespace)) {
            $location.url('/organization/' + namespace + '?tab=robots&showRobot=' + created.name);
          } else {
            $location.url('/user/' + namespace + '?tab=robots&showRobot=' + created.name);
          }
        });
      };

      $scope.createTeam = function(context) {
        var namespace = $scope.getNamespace(context);
        if (!namespace || !UserService.isNamespaceAdmin(namespace)) { return; }

        CreateService.askCreateTeam(namespace, function(created) {
            $location.url('/organization/' + namespace + '/teams/' + created.name);
        });
      };
    }
  };
  return directiveDefinitionObject;
});