text: (function() {
      "use strict";
  
      function QueryBuilderOverlayController($scope, templateQueryResource, localizationService) {
  
          var everything = "";
          var myWebsite = "";
          var ascendingTranslation = "";
          var descendingTranslation = "";
  
          var vm = this;
  
          vm.properties = [];
          vm.contentTypes = [];
          vm.conditions = [];
  
          vm.datePickerConfig = {
              pickDate: true,
              pickTime: false,
              format: "YYYY-MM-DD"
          };
  
          vm.chooseSource = chooseSource;
          vm.getPropertyOperators = getPropertyOperators;
          vm.addFilter = addFilter;
          vm.trashFilter = trashFilter;
          vm.changeSortOrder = changeSortOrder;
          vm.setSortProperty = setSortProperty;
          vm.setContentType = setContentType;
          vm.setFilterProperty = setFilterProperty;
          vm.setFilterTerm = setFilterTerm;
          vm.changeConstraintValue = changeConstraintValue;
          vm.datePickerChange = datePickerChange;
  
          function onInit() {
  
              vm.query = {
                  contentType: {
                      name: everything
                  },
                  source: {
                      name: myWebsite
                  },
                  filters: [
                      {
                          property: undefined,
                          operator: undefined
                      }
                  ],
                  sort: {
                      property: {
                          alias: "",
                          name: ""
                      },
                      direction: "ascending", //This is the value for sorting sent to server
                      translation: {
                          currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog
                          ascending: ascendingTranslation,
                          descending: descendingTranslation
                      }
                  }
              };
  
              templateQueryResource.getAllowedProperties()
                  .then(function(properties) {
                      vm.properties = properties;
                  });
  
              templateQueryResource.getContentTypes()
                  .then(function(contentTypes) {
                      vm.contentTypes = contentTypes;
                  });
  
              templateQueryResource.getFilterConditions()
                  .then(function(conditions) {
                      vm.conditions = conditions;
                  });
  
              throttledFunc();
  
          }
  
          function chooseSource(query) {
              vm.contentPickerOverlay = {
                  view: "contentpicker",
                  show: true,
                  submit: function(model) {
  
                      var selectedNodeId = model.selection[0].id;
                      var selectedNodeName = model.selection[0].name;
  
                      if (selectedNodeId > 0) {
                          query.source = { id: selectedNodeId, name: selectedNodeName };
                      } else {
                          query.source.name = myWebsite;
                          delete query.source.id;
                      }
  
                      throttledFunc();
  
                      vm.contentPickerOverlay.show = false;
                      vm.contentPickerOverlay = null;
                  },
                  close: function(oldModel) {
                      vm.contentPickerOverlay.show = false;
                      vm.contentPickerOverlay = null;
                  }
              };
          }
  
          function getPropertyOperators(property) {
              var conditions = _.filter(vm.conditions,
                  function(condition) {
                      var index = condition.appliesTo.indexOf(property.type);
                      return index >= 0;
                  });
              return conditions;
          }
  
          function addFilter(query) {
              query.filters.push({});
          }
  
          function trashFilter(query, filter) {
              for (var i = 0; i < query.filters.length; i++) {
                  if (query.filters[i] == filter) {
                      query.filters.splice(i, 1);
                  }
              }
              //if we remove the last one, add a new one to generate ui for it.
              if (query.filters.length == 0) {
                  query.filters.push({});
              }
  
          }
  
          function changeSortOrder(query) {
              if (query.sort.direction === "ascending") {
                  query.sort.direction = "descending";
                  query.sort.translation.currentLabel = query.sort.translation.descending;
              } else {
                  query.sort.direction = "ascending";
                  query.sort.translation.currentLabel = query.sort.translation.ascending;
              }
              throttledFunc();
          }
  
          function setSortProperty(query, property) {
              query.sort.property = property;
              if (property.type === "datetime") {
                  query.sort.direction = "descending";
                  query.sort.translation.currentLabel = query.sort.translation.descending;
              } else {
                  query.sort.direction = "ascending";
                  query.sort.translation.currentLabel = query.sort.translation.ascending;
              }
              throttledFunc();
          }
  
          function setContentType(contentType) {
              vm.query.contentType = contentType;
              throttledFunc();
          }
  
          function setFilterProperty(filter, property) {
              filter.property = property;
              filter.term = {};
              filter.constraintValue = "";
          }
  
          function setFilterTerm(filter, term) {
              filter.term = term;
              if (filter.constraintValue) {
                  throttledFunc();
              }
          }
  
          function changeConstraintValue() {
              throttledFunc();
          }
  
          function datePickerChange(event, filter) {
              if (event.date && event.date.isValid()) {
                  filter.constraintValue = event.date.format(vm.datePickerConfig.format);
                  throttledFunc();
              }
          }
  
          var throttledFunc = _.throttle(function() {
  
                  templateQueryResource.postTemplateQuery(vm.query)
                      .then(function(response) {
                          $scope.model.result = response;
                      });
  
              },
              200);
  
          localizationService.localizeMany([
                  "template_allContent", "template_websiteRoot", "template_ascending", "template_descending"
              ])
              .then(function(res) {
                  everything = res[0];
                  myWebsite = res[1];
                  ascendingTranslation = res[2];
                  descendingTranslation = res[3];
                  onInit();
              });
      }
  
      angular.module("umbraco").controller("Umbraco.Overlays.QueryBuilderController", QueryBuilderOverlayController);
  
  })();