if (!window.webmail) {
   var webmail = {
      domains: [],
      errorCode: null,
      errorName: null,
      ready: false,
      initBranding: null,
      isSafari: window.navigator.userAgent.indexOf("Safari/") > 0 && window.navigator.userAgent.indexOf("Chrome/") <= 0,
      username: "",

      init: function () {
         if (webmail.ready === true) {
            return;
         }

         webmail.initForm();

         if (webmail.initBranding) {
            webmail.initBranding();
         }

         if (!webmail.cookies.isSupported()) {
            webmail.showError("cookies-disabled");
         } else {
            var errorCode = webmail.utilities.getQueryStringParameter("reason");
            if (errorCode && errorCode.length > 0) {
               webmail.showError(errorCode);
            }
         }

         webmail.ready = true;
      },

      initForm: function () {
         webmail.loginForm = document.getElementById("login");
         webmail.emailAddressElement = document.getElementById("emailaddress");
         webmail.usernameElement = document.getElementById("username");
         webmail.rememberElement = document.getElementById("remember");
         webmail.passwordElement = document.getElementById("password");
         webmail.messageElement = document.getElementById("message");

         if (webmail.loginForm && webmail.usernameElement && webmail.emailAddressElement && webmail.passwordElement && webmail.messageElement && typeof webmail.getErrorText === "function") {
            for (var i = 0; i < webmail.loginForm.elements.length; i++) {
               webmail.loginForm.elements[i].disabled = false;
            }

            webmail.loginForm.classList.remove("disabled");
            webmail.loginForm.noValidate = true;
            webmail.loginForm.addEventListener("submit", webmail.validateForm);
            webmail.loginForm.addEventListener("submit", webmail.storePreferences);
            webmail.loginForm.addEventListener("submit", webmail.submitForm);

            webmail.usernameElement.addEventListener("keyup", webmail.hintDomain);
            webmail.usernameElement.addEventListener("input", webmail.hintDomain);
            webmail.usernameElement.addEventListener("change", webmail.hintDomain);

            if (webmail.isSafari) {
               webmail.usernameElement.addEventListener("DOMFocusIn", webmail.hintDomain, false);
               webmail.usernameElement.addEventListener("DOMFocusOut", webmail.hintDomain, false);
               webmail.usernameElement.addEventListener("mouseup", webmail.hintDomain, true);
               webmail.usernameElement.addEventListener("mousedown", webmail.hintDomain, true);
            }

            webmail.defaultDomain = webmail.cookies.read("defaultHostDomainName") || webmail.domains[0];
            if (webmail.rememberElement) {
               var lastLoginName = webmail.cookies.read("lastLoginName");
               if (lastLoginName) {
                  webmail.usernameElement.value = lastLoginName;
                  webmail.rememberElement.checked = true;
                  webmail.passwordElement.focus();
               }
            }

            window.setTimeout(webmail.hintDomain, 10);
         }
      },

      validateForm: function (event) {
         event = event || window.event;
         var formValid = true;
         for (var i = 0; i < webmail.loginForm.elements.length; i++) {
            formValid &= webmail.validateElement(event, webmail.loginForm.elements[i]);
         }

         if (formValid && !webmail.utilities.isEmailAddress(webmail.emailAddressElement.innerText)) {
            formValid = false;
            webmail.showError("error.user.failed-login");
         }

         if (!formValid && event.preventDefault) {
            event.preventDefault();
         }

         webmail.loginForm.validity = { valid: formValid };
         return formValid;
      },

      validateElement: function (event, elementObject) {
         event = event || window.event;
         if (event) {
            var element = elementObject || event.target || event.srcElement;
            if (element.nodeType) {
               var valueMissing = (element.hasAttribute("required") && element.value.length === 0);
               var patternMismatch = (element.hasAttribute("data-pattern") && element.patternValidity !== null && element.patternValidity === false);
               var elementContainer = element.closest(".form-input");

               if (elementContainer) {
                  elementContainer.className = elementContainer.className.replace(/\s?invalid-?\w*/, "");
                  if (valueMissing) {
                     elementContainer.classList.add("invalid-required");
                  }
                  if (patternMismatch) {
                     elementContainer.classList.add("invalid-pattern");
                  }
               }

               var valid = !valueMissing && !patternMismatch;
               if (valid) {
                  element.removeEventListener("keyup", webmail.validateElement);
                  element.removeEventListener("input", webmail.validateElement);
                  element.removeEventListener("change", webmail.validateElement);
               } else {
                  element.addEventListener("keyup", webmail.validateElement);
                  element.addEventListener("input", webmail.validateElement);
                  element.addEventListener("change", webmail.validateElement);
               }
               return valid;
            }
         }
         return true;
      },

      hintDomain: function (event) {
         event = event || window.event;
         if (event && event.which === 32) {
            event.preventDefault();
         } else if (webmail.usernameElement.value != webmail.username) {
            webmail.usernameElement.value = webmail.username = webmail.usernameElement.value.toLocaleLowerCase().replace(/\s/g, "");

            if (webmail.usernameElement.value.length > 0) {
               var usernameSplit = webmail.usernameElement.value.split("@");
               if (usernameSplit.length < 3) {
                  webmail.usernameElement.patternValidity = !webmail.usernameElement.hasAttribute("data-pattern") || webmail.usernameElement.getAttribute("data-pattern") !== "domain";

                  var usernamePart = usernameSplit[0];
                  var domainPart = usernameSplit.length === 2 && usernameSplit[1].length > 0 ? usernameSplit[1] : webmail.defaultDomain;

                  webmail.usernameElement.patternValidity = domainPart.length === 0 || webmail.domains.indexOf(domainPart) >= 0;
                  for (var i = 0; i < webmail.domains.length && webmail.domains.indexOf(domainPart) < 0; i++) {
                     if (webmail.domains[i].indexOf(domainPart) === 0) {
                        webmail.defaultDomain = domainPart = webmail.domains[i];
                        webmail.usernameElement.patternValidity = true;
                     }
                  }

                  webmail.emailAddressElement.innerHTML = "<span class=\"usernamepart\">" + usernamePart + "</span>@" + domainPart;
               }
            } else {
               webmail.emailAddressElement.innerHTML = "";
            }
         }
      },

      storePreferences: function (event) {
         if (webmail.loginForm.validity.valid) {
            webmail.cookies.create("defaultHostDomainName", webmail.defaultDomain, 365);
            if (webmail.rememberElement) {
               if (webmail.rememberElement.checked) {
                  webmail.cookies.create("lastLoginName", webmail.usernameElement.value, 365);
               } else {
                  webmail.cookies.create("lastLoginName", webmail.usernameElement.value, -1);
               }
            }
         }
      },

      submitForm: function (event) {
         event = event || window.event;
         if (event.preventDefault) {
            event.preventDefault();
         }

         if (webmail.loginForm.validity.valid) {
            webmail.hideError();
            webmail.loginForm.classList.add("loading");
            if (webmail.usernameElement.value.indexOf("@") > 0) {
               webmail.usernameElement.value = webmail.emailAddressElement.innerText;
            }
            
            webmail.utilities.post(
               "/LoginHandler.ashx",
               "emailaddress=" + encodeURIComponent(webmail.emailAddressElement.innerText),
               function (respone) {
                   if (respone.error || !respone.target) {
                       if (respone.error == "maintenance") {
                           window.location.reload();
                       } else {
                           webmail.showError(respone.error);
                       }
                   } else {
                       webmail.oxLogin(respone.target);
                   }
               },
               webmail.showError
            );
         }
         return false;
      },

      oxLogin: function (target) {
         var clientToken = webmail.utilities.uuid();
         webmail.utilities.post(
            target + "/ajax/login?action=tokenLogin&authId=" + webmail.utilities.uuid(),
            "login=" + encodeURIComponent(webmail.emailAddressElement.innerText) + "&password=" + encodeURIComponent(webmail.passwordElement.value) + "&clientToken=" + clientToken +
            "&autoLogin=false&staySignedIn=false&jsonResponse=true&client=open-xchange-appsuite&version=WebmailLogin&uiWebPath=/appsuite/",
            function (respone) {
               if (respone.error || !respone.url) {
                   webmail.showError(respone.code, respone.error_desc);
               } else {
                  window.location.replace(target + respone.url + "&clientToken=" + clientToken);
               }
            },
            webmail.showError
         );
      },

      showError: function (errorCode,errorName) {
         webmail.errorCode = errorCode;
         webmail.errorName = errorName;
         webmail.loginForm.classList.remove("loading");
         webmail.messageElement.innerHTML = webmail.getErrorText(errorCode, errorName);
         webmail.messageElement.style.display = "block";
      },

      hideError: function () {
         webmail.errorCode = null;
         webmail.errorName = null;
         webmail.messageElement.innerHTML = "";
         webmail.messageElement.style.display = "none";
         webmail.messageElement.classList.remove("invalid");
      },

      cookies: {
         create: function (name, value, days) {
            var cookie_string, date;
            if (value) {
               cookie_string = name + "=" + escape(value);
            } else {
               cookie_string = name + "=";
            }

            if (days) {
               date = new Date();
               date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
               cookie_string += "; expires=" + date.toGMTString();
            }
            cookie_string += "; path=/";

            if (window.location.protocol === 'https:') {
               cookie_string += "; Secure";
            }

            document.cookie = cookie_string;
         },

         read: function readCookie(name) {
            var cookies = document.cookie.split('; ');
            while (cookies.length > 0) {
               var cookie = cookies.pop().split('=');
               if (cookie[0] === name) {
                  return unescape(cookie[1]);
               }
            }

            return undefined;
         },

         isSupported: function () {
            var cookieName = "cookieSupportTest" + Math.round(Math.random() * 100000);
            var cookieValue = "cookieSupportTestValue";
            webmail.cookies.create(cookieName, cookieValue);
            var isSupported = (webmail.cookies.read(cookieName) === cookieValue);
            webmail.cookies.create(cookieName, cookieValue, -1);
            return isSupported;
         }
      },

      utilities: {
         post: function (url, body, successHandler, errorHandler) {
            var http = new XMLHttpRequest();
            http.onreadystatechange = function () {
               if (http.readyState == XMLHttpRequest.DONE) {
                  var status = http.status;
                  if (status >= 200 && status < 400) {
                     successHandler(JSON.parse(http.responseText));
                  } else {
                     errorHandler(status);
                  }
               }
            };
            http.open("POST", url, true);
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            http.send(body);
         },

         getQueryStringParameter: function (parameterName) {
            var plusRegex = /\+/g;
            var search = /([^&=]+)=?([^&]*)/g;
            var query = window.location.search.substring(1);
            var urlParams = {};

            var decode = function (string) {
               return decodeURIComponent(string.replace(plusRegex, " "));
            };

            var match = search.exec(query);
            while (match !== null) {
               urlParams[decode(match[1])] = decode(match[2]);
               match = search.exec(query);
            }

            return urlParams[parameterName];
         },

         uuid: function() {
            function hex(len, x) {
               if (x === undefined) x = Math.random();
               var s = new Array(len);
               for (var i = 0; i < len; i++) {
                  x *= 16;
                  var digit = x & 15;
                  s[i] = digit + (digit < 10 ? 48 : 87); // '0' and 'a' - 10
               }
               return String.fromCharCode.apply(String, s);
            }
            return [hex(8), "-", hex(4), "-4", hex(3), "-", hex(4, 0.5 + Math.random() / 4), "-", hex(12)].join("");
         },

         isEmailAddress: function (emailAddress) {
            var search = /^[a-z0-9!#$%&*+\-/=?^_`{}~]{1,}(?:\.[a-z0-9!#$%&*+\-/=?^_`{}~]{1,}){0,}@\[{0,1}(?:[a-z0-9_-]{1,}\.){1,}[a-z0-9]{1,}\]{0,1}$/i;
            var match = search.exec(emailAddress);
            return match;
         },
      }
   }
}

var requestIdentifier = webmail.utilities.uuid();
(function () {
   // Pop-out of any parent frame
   if (window.location.href !== window.top.location.href) {
      window.top.location.href = window.location.href;
   } else {
      if (parent.requestIdentifier !== requestIdentifier) {
         window.top.location.href = window.location.href;
      }
   }

   window.onload = function () {
      webmail.init();
   };

   document.onreadystatechange = function () {
      if ((document.readyState === "loaded") || (document.readyState === "complete")) {
         webmail.init();
      }
   };
}());