define(
    "spaceControllers",
    [ "SHARED/jquery", "SHARED/uiCalendar", "SHARED/CalDateTimePicker",
        "SHARED/DateTimeFormatter", "SHARED/mentionsPlugin" , "SHARED/juzu-ajax"], function($,
        timePicker, otherTimePicker, dateFormatter, mentionsPlugin, jz) {
      var spaceCtrl = function($scope, $q, $timeout, $http, $filter, $window) {

        var spaceContainer = $('#spaceAddon');
        var deferred = $q.defer();
        $scope.spacesFilter='active';
        $scope.showForm = false;
        $scope.submittingForm = false;
        $scope.spaces = [];
        $scope.newSpace = {tagIndex:'1'};
        $scope.sortType = 'name';
        $scope.sortReverse = false;
        $scope.flows = {};
        $scope.slaList = {};
        $scope.subscriptionList = {};
        $scope.dateFormat = dateFormatter.masks["isoDate"].replace("mm", "MM");
        $scope.dateInputFields = [];

        $scope.sortTicketsType = 'tagName';
        $scope.sortTicketsReverse = false;

        $scope.initForm = function(space) {
          if(space) {
            $scope.newSpace = space;
          } else {
            $scope.newSpace = {tagIndex:'1'};
          }
          $scope.showForm = true;
          $scope.spaceLink = null;
          $scope.setResultMessage("", "info");
        }


        $scope.loadTickets = function(space) {
          $scope.setResultMessage($scope.i18n.loading, "info");
          $http({
            data : space,
            method : 'POST',
            headers : {
              'Content-Type' : 'application/json; charset=UTF-8'
            },
            url : spaceContainer.jzURL('SpaceController.getTicketsOfSpace')
          }).then(function successCallback(data) {
            $scope.setResultMessage("", "info");
            $scope.tickets = data.data;
            $scope.showForm = false;
            $scope.submittingForm = false;
            $scope.showTickets = true;
          }, function errorCallback(data) {
            $scope.showTickets = false;
            $scope.setResultMessage(data, "error");
          });
        };

        $scope.loadFlows = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.getFlows')
          }).then(function successCallback(data) {
            $scope.flows = data.data;
            deferred.resolve(data);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        }

        $scope.loadSlaList = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.loadSlaList')
          }).then(function successCallback(data) {
            $scope.slaList = data.data;
            deferred.resolve(data);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        }

        $scope.loadSubscriptionList = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.loadSubscriptionList')
          }).then(function successCallback(data) {
            $scope.subscriptionList = data.data;
            deferred.resolve(data);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        }

        $scope.loadSpaces = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.getSpaces') + "&filter=" + $scope.spacesFilter
          }).then(function successCallback(data) {
            $scope.setResultMessage(data, "success");
            $scope.spaces = data.data;

            $timeout(function() {
              $scope.setResultMessage("", "info")
            }, 3000);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        };

        $scope.loadActiveSpaces = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.getActiveSpaces')
          }).then(function successCallback(data) {
            $scope.setResultMessage(data, "success");
            $scope.spaces = data.data;

            $timeout(function() {
              $scope.setResultMessage("", "info")
            }, 3000);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        };

        $scope.loadDeactvatedSpaces = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.getDeactvatedSpaces')
          }).then(function successCallback(data) {
            $scope.setResultMessage(data, "success");
            $scope.spaces = data.data;

            $timeout(function() {
              $scope.setResultMessage("", "info")
            }, 3000);
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        };

        $scope.loadBundles = function() {
          $http({
            method : 'GET',
            url : spaceContainer.jzURL('SpaceController.getBundle') + "&locale=" + eXo.env.portal.language
          }).then(function successCallback(data) {
            $scope.i18n = data.data;
            deferred.resolve(data);
            $scope.initMentions();
          }, function errorCallback(data) {
            $scope.setResultMessage(data, "error");
          });
        }

        $scope.updateSpace = function() {
          $scope.setResultMessage($scope.i18n.savingSpace, "info");
          $scope.showForm = false;
          $scope.submittingForm = true;
          $http({
            data : $scope.newSpace,
            method : 'POST',
            headers : {
              'Content-Type' : 'application/json'
            },
            url : spaceContainer.jzURL('SpaceController.updateSpace')
          }).then(function successCallback(data) {
            if (data && data.data.length > 0) {
              $scope.spaceLink = "/portal/g/:spaces:" + data.data;
            }
            $scope.setResultMessage($scope.i18n.spaceUpdated , "success");
            $scope.newSpace = {};
            $scope.loadSpaces();
            $scope.showForm = false;
            $scope.submittingForm = false;
          }, function errorCallback(data) {
            $scope.submittingForm = false;
            $scope.showForm = true;
            if(data && data.data.indexOf('#') == 0) {
              data = data.data.substring(4);
              $scope.setResultMessage($scope.i18n[data], "error");
            } else {
              $scope.setResultMessage($scope.i18n.spaceSubmitionError, "error");
            }
          });
          $window.scrollTo(0, 0);

        }

        $scope.saveSpace = function() {
          $scope.newSpace.members = $scope.getMentions("spaceMembers");
          var managersGroup = $scope.getMentions("managersGroupId");
          if (managersGroup && managersGroup.length > 0) {
            if (managersGroup.length > 1) {
              $scope.setResultMessage($scope.i18n.onlyOneGroup, "warning");
              return;
            }
            $scope.newSpace.managersGroupId = managersGroup[0];
          }
          var invitedMembersGroup = $scope.getMentions("membersInvitedGroupId");
          if (invitedMembersGroup && invitedMembersGroup.length > 0) {
            if (invitedMembersGroup.length > 1) {
              $scope.setResultMessage($scope.i18n.onlyOneGroup, "warning");
              return;
            }
            $scope.newSpace.invitedMembersGroupId = invitedMembersGroup[0];
          }
          $scope.newSpace.taskDefaultAssignee = $scope.getMentions("spaceTaskDefaultAssignee");
          if ($scope.newSpace.taskDefaultAssignee
              && $scope.newSpace.taskDefaultAssignee.length > 0) {
            if ($scope.newSpace.taskDefaultAssignee.length > 1) {
              $scope.setResultMessage($scope.i18n.onlyOneTaskAssignee,
                  "warning");
              return;
            }
            $scope.newSpace.taskDefaultAssignee = $scope.newSpace.taskDefaultAssignee[0];
          }
          var validationMessage = $scope.validateSpaceForm();
          if (validationMessage) {
            $scope.setResultMessage(validationMessage, "warning");
            return;
          }

          $scope.setResultMessage($scope.i18n.savingSpace, "info");
          $scope.showForm = false;
          $scope.submittingForm = true;
          $http({
            data : $scope.newSpace,
            method : 'POST',
            headers : {
              'Content-Type' : 'application/json'
            },
            url : spaceContainer.jzURL('SpaceController.saveSpace')
          }).then(function successCallback(data) {
            if (data && data.data.length > 0) {
              $scope.spaceLink = "/portal/g/:spaces:" + data.data;
            }
            $scope.setResultMessage($scope.i18n.spaceSubmitted , "success");
            $scope.newSpace = {};
            $scope.loadSpaces();
            $scope.showForm = false;
            $scope.submittingForm = false;
          }, function errorCallback(data) {
            $scope.submittingForm = false;
            $scope.showForm = true;
            if(data && data.data.indexOf('#') == 0) {
              data = data.data.substring(4);
              $scope.setResultMessage($scope.i18n[data], "error");
            } else {
              $scope.setResultMessage($scope.i18n.spaceSubmitionError, "error");
            }
          });
          $window.scrollTo(0, 0);
        }

        $scope.editSpace = function(space) {
          $scope.showForm = true;
          $scope.initForm(space);
        };

        $scope.getMentions = function(id) {
          var data = $("#"+id).parents('form:first')
          .parent().data(id);
          if(data && data.mentions && data.mentions.length > 0) {
            return data.mentions;
          }
          return null;
        }

        // function which set the result message with the given style
        $scope.setResultMessage = function(text, type) {
          $scope.resultMessageClass = "alert-" + type;
          $scope.resultMessageClassExt = "uiIcon"
              + type.charAt(0).toUpperCase() + type.slice(1);
          $scope.resultMessage = text;
        }

        $scope.validateSpaceForm = function() {
          if (!$scope.newSpace.name) {
            return $scope.i18n.validateAddTitle;
          }
          if (!$scope.newSpace.limitTicketsNumber || isNaN($scope.newSpace.limitTicketsNumber)) {
            return $scope.i18n.validateLimitTicketsNumber;
          }
          if (!$scope.newSpace.tagPrefix) {
            return $scope.i18n.validateTagPrefix;
          }
          if ($scope.newSpace.tagPrefix.length > 50) {
            return $scope.i18n.validateTagPrefixLength;
          }
          if (!$scope.newSpace.tagIndex || isNaN($scope.newSpace.tagIndex)) {
            return $scope.i18n.validateTagIndex;
          }
          if (!$scope.newSpace.taskPriority) {
            return $scope.i18n.validateTaskPriority;
          }
          if (!$scope.newSpace.taskDefaultAssignee
              || !$scope.newSpace.taskDefaultAssignee.id
              || $scope.newSpace.taskDefaultAssignee.id.length == 0) {
            return $scope.i18n.validateTaskAssignee;
          }
        };

        $scope.initMentions = function() {
          spaceContainer.find('#managersGroupId').exoMentions({
            onDataRequest : function(mode, query, callback) {
              var _this = this;
              spaceContainer.jzAjax('SpaceController.findGroups()', {
                data : {
                  query : query
                },
                success : function(data) {
                  callback.call(_this, data);
                }
              });
            },
            elastic : {
              maxHeight : '52px',
              minHeight : '22px',
              marginButton : '4px',
              enableMargin : false
            },
            messages : {
              helpSearch: $scope.i18n.mentionsTypeToSearchUsers,
              searching: $scope.i18n.mentionsSearchingFor,
              foundNoMatch : $scope.i18n.mentionsNoMatchingForGroups
            },
            minChars : 3,
            cacheResult : true,
          });
          spaceContainer.find('#membersInvitedGroupId').exoMentions({
            onDataRequest : function(mode, query, callback) {
              var _this = this;
              spaceContainer.jzAjax('SpaceController.findGroups()', {
                data : {
                  query : query
                },
                success : function(data) {
                  callback.call(_this, data);
                }
              });
            },
            elastic : {
              maxHeight : '52px',
              minHeight : '22px',
              marginButton : '4px',
              enableMargin : false
            },
            messages : {
              helpSearch: $scope.i18n.mentionsTypeToSearchUsers,
              searching: $scope.i18n.mentionsSearchingFor,
              foundNoMatch : $scope.i18n.mentionsNoMatchingForGroups
            },
            minChars : 3,
            cacheResult : true,
          });


          spaceContainer.find('#spaceMembers').exoMentions({
            onDataRequest : function(mode, query, callback) {
              var _this = this;
              spaceContainer.jzAjax('SpaceController.findUsers()', {
                data : {
                  query : query
                },
                success : function(data) {
                  callback.call(_this, data);
                }
              });
            },
            elastic : {
              maxHeight : '52px',
              minHeight : '22px',
              marginButton : '4px',
              enableMargin : false
            },
            messages : {
              helpSearch: $scope.i18n.mentionsTypeToSearchUsers,
              searching: $scope.i18n.mentionsSearchingFor,
              foundNoMatch : $scope.i18n.mentionsNoMatchingForUsers
            },
            minChars : 3,
            cacheResult : true,
          });

          spaceContainer.find('#spaceTaskDefaultAssignee').exoMentions({
            onDataRequest : function(mode, query, callback) {
              var _this = this;
              spaceContainer.jzAjax('SpaceController.findUsers()', {
                data : {
                  query : query
                },
                success : function(data) {
                  callback.call(_this, data);
                }
              });
            },
            elastic : {
              maxHeight : '52px',
              minHeight : '22px',
              marginButton : '4px',
              enableMargin : false
            },
            messages : {
              helpSearch: $scope.i18n.mentionsTypeToSearchUsers,
              searching: $scope.i18n.mentionsSearchingFor,
              foundNoMatch : $scope.i18n.mentionsNoMatchingForUsers
            },
            minChars : 3,
            cacheResult : true,
          });
        }

          $scope.setStartDateError = function(text, type) {
                  $scope.startDateErrorClass = "error";
                  $scope.startDateErrorMessage = text;
                }
                $scope.setEndDateError = function(text, type) {
                  $scope.endDateErrorClass = "error";
                  $scope.endDateErrorMessage = text;
                }
                $scope.setStartAfterEndDateError = function(text, type) {
                  $scope.StartAfterEndDateErrorClass = "error";
                  $scope.StartAfterEndDateErrorMessage = text;
                }



        $scope.validateDate = function(txtDate) {
          if (!txtDate) {
            return $scope.i18n.validateAddStartDate;
          }
          if (isNaN(Date.parse(txtDate))) {
            return $scope.i18n.validateStartDateFormat;
          }
        };
        $scope.validateEndDate = function(start,end){
        if (Date.parse(end) <= Date.parse(start)) {
            return $scope.i18n.validateEndAfterStartDates;
          }
        }

        $scope.setDateTimeField = function(inputFieldId) {
          $scope.dateInputFields[$scope.dateInputFields.length] = inputFieldId;
          timePicker.isDisplayTime = true;
          $("#" + inputFieldId).on("change", function(evt) {
            $scope.newSpace[evt.target.id] = evt.target.value;
          });
          timePicker.hideCalendarHandler = function(evt) {
            $scope.refreshController();
            console.log(evt.srcElement.value);
            if (evt.type == "click"
                && $scope.dateInputFields.indexOf(evt.srcElement.id) >= 0) {
              return;
            }
            timePicker.hide();
          }
          $("#" + inputFieldId).focus(
              function() {
                otherTimePicker.isDisplayTime = true;
                timePicker.init(document.getElementById(inputFieldId), true,
                    $scope.dateFormat, "", otherTimePicker.months.toString());
              });
          $("#" + inputFieldId).keyup(function() {
            eXo.webui.UICalendar.show();
          });
          $("#" + inputFieldId).focus(function(event) {
            event.cancelBubble = true;
          });
        }
		$scope.refreshController = function() {
          try {
            $scope.$apply();
            $scope.$digest();
              } catch (excep) {
                    // Nothing here
              }
            };

        $scope.loadBundles();
        $scope.loadFlows();
        $scope.loadSlaList();
        $scope.loadSubscriptionList();
        $scope.loadSpaces();
        $scope.setDateTimeField("subscriptionStartDate");
        $scope.setDateTimeField("subscriptionEndDate");

        $('#spaceAddon').css('visibility', 'visible');
        $(".spaceLoadingBar").remove();
      };
      return spaceCtrl;
    });