app.directive('zlContainer', function() {
  return {
    restrict: 'E',
    replace: false,
    templateUrl: 'directives/container/container.html',
    scope: {
      entity: '@',
      item: '=',
      lookup: '=',

      label: '@',
      var: '@',

      key: '@',

      isVisible: '&?',
      isMovable: '@',
      noInsert: '@',
      removable: '@',

      approvalMaxLevel: '@'
    },
    controller: function($scope, $rootScope, $controller, $timeout) {
      if ($scope.key) {
        $scope.newContainerItem = {};
      }
      else {
        $scope.newContainerItem = "";
      }

      $scope.append = function(newContainerItem) {
        append(newContainerItem, function(err) {
          if (err) {
            return swal("Atenção", err, "warning");
          }

          //clear new container item fields
          if ($scope.key) {
            $scope.newContainerItem = {};
          }
          else {
            $scope.newContainerItem = "";
          }
        });
      };

      $scope.remove = function(containerItem) {
        var index = $scope.item[$scope.var].indexOf(containerItem);
        if (index != -1) {
          $scope.item[$scope.var].splice(index, 1);
        }
      };

      $scope.validate = function(newContainerItem) {
        if (!newContainerItem) {
          return true;
        }

        if ($scope.key) {
          if (Object.keys(newContainerItem).length === 0 && JSON.stringify(newContainerItem) === JSON.stringify({})) {
            return true;
          }
        }

        if (typeof $scope.getError === 'function') {
          var response = $scope.getError(newContainerItem, $scope.item[$scope.var]);
          if (response.disabled) {
            $scope.console = response.tooltip;
            return true;
          }
        }

        $scope.console = null;
        return false;
      };

      $scope.pushBack = function(index) {
        var _containerItem = $scope.item[$scope.var].splice(index, 1);
        $scope.item[$scope.var].splice(index - 1, 0, _containerItem[0]);
      };

      $scope.pushForward = function(index) {
        var _containerItem = $scope.item[$scope.var].splice(index, 1);
        $scope.item[$scope.var].splice(index + 1, 0, _containerItem[0]);
      };

      //$timeout is only ready after directive has fully loaded
      //this way when the controller loads, $scope will be fully populated
      $timeout(function() {
        //inject child controller
        $controller($scope.var + 'Ctrl', {$scope: $scope});
      });

      function append(newContainerItem, callback) {
        var i, property;
        if (!$scope.item[$scope.var]) {
          $scope.item[$scope.var] = [];
        }

        //check if containerItem is not empty
        if ($scope.key) {
          var key = {
            property: null,
            key: null
          };
          if (newContainerItem[$scope.key]) {
            key.key = newContainerItem[$scope.key];
          }
          else {
            for (property in newContainerItem) {
              if (newContainerItem[property][$scope.key]) {
                key.property = property;
                key.key = newContainerItem[property][$scope.key];
                break;
              }
            }
          }

          if (key.key) {
            //check if containerItem already exists in container
            for (i = 0; i < $scope.item[$scope.var].length; i++) {
              var obj = key.property ? $scope.item[$scope.var][i][key.property] : $scope.item[$scope.var][i];
              if (obj[$scope.key] === key.key) {
                return callback('Registo duplicado em ' + $scope.label);
              }
            }
          }
        }
        else {
          for (i = 0; i < $scope.item[$scope.var].length; i++) {
            if ($scope.item[$scope.var][i] === newContainerItem) {
              return callback('Registo duplicado em ' + $scope.label);
            }
          }
        }

        //append item to container
        $scope.item[$scope.var].unshift(newContainerItem);

        //approvable containers only
        if ($scope.approvalMaxLevel) {
          //assign approval
          if ($scope.approvalMaxLevel) {
            newContainerItem.approval = {
              level: $rootScope.login.role.approvalLevel,
              maxLevel: $scope.approvalMaxLevel
            };
          }
        }

        callback();
      }
    }
  };
});

