(function(window, undefined) {
  var i18n = {
    /* The loaded JSON message store will be set on this object */
    msgStore: {},
    msgStoreBackup: {},
    msgDatatablesStore: {},
    msgAdditionStores: {},
    msgAdditionStoreBackup: {},
    language: {},
    lang_names: {},
    lang_codes: {},
    lang_additions: {},
    translate: function(textkey, addition) {
      var res = undefined;
      if (addition) {
        var addtionstore = this.msgAdditionStores[addition];
        if (addtionstore != undefined) {
          res = this.msgAdditionStores[addition][textkey];
        }
      }
      for (var i = 0; res == undefined && this.lang_additions && i < this.lang_additions.length; i++) {
        var addtionstore = this.msgAdditionStores[this.lang_additions[i]];
        if (addtionstore != undefined) {
          res = addtionstore[textkey];
        }
      }
      if (res == undefined) {
        res = this.msgStore[textkey];
      }
      for (var i = 0; res == undefined && this.lang_additions && i < this.lang_additions.length; i++) {
        var addtionstore = this.msgAdditionStoreBackup[this.lang_additions[i]];
        if (addtionstore != undefined) {
          res = addtionstore[textkey];
        }
      }

      if (res == undefined) {
        res = this.msgStoreBackup[textkey];
      }
      if (res == undefined) {
        // Ups...
        return textkey;
      }
      return res;
    },
    translateAlert: function(textkey, addition) {
      var res = undefined;
      if (addition) {
        var addtionstore = this.msgAdditionStores[addition];
        if (addtionstore != undefined) {
          res = this.msgAdditionStores[addition][textkey];
        }
      }
      for (var i = 0; res == undefined && this.lang_additions && i < this.lang_additions.length; i++) {
        var addtionstore = this.msgAdditionStores[this.lang_additions[i]];
        if (addtionstore != undefined) {
          res = addtionstore[textkey];
        }
      }

      if (res == undefined) {
        res = this.msgStore[textkey];
      }
      for (var i = 0; res == undefined && this.lang_additions && i < this.lang_additions.length; i++) {
        var addtionstore = this.msgAdditionStoreBackup[this.lang_additions[i]];
        if (addtionstore != undefined) {
          res = addtionstore[textkey];
        }
      }
      if (res == undefined) {
        res = this.msgStoreBackup[textkey];
      }
      if (res == undefined) {
        // Ups...
        return textkey;
      }
      // we use html coding in the language files, so decode this to normal text for alert boxes
      return $("<p>").html(res).text();
    },
    setLanguage: function(lang) {
      if (this.lang_codes.indexOf(lang.substring(0, 2)) != -1) {
        this.language = lang.substring(0, 2);
      } else {
        this.language = this.lang_codes[0];
      }
      getRequest(
        '/locale/' + this.language + '.json',
        function(data) {
          i18n.msgStore = JSON.parse(data);
        },
        function() {
          console.log("Error: language file " + this.language + " not found, using fallback 'en'!");
          getRequest(
            '/locale/en.json',
            function(data) {
              i18n.msgStoreBackup = JSON.parse(data);
            },
            function() {}
          );
        }
      );
      for (var i = 0; this.lang_additions && i < this.lang_additions.length; i++) {
        var additionname = this.lang_additions[i];
        getRequest(
          '/locale/' + additionname + '_' + this.language + (additionname == 'datatables' ? '.lang' : '.json'),
          function(data) {
            if (additionname == 'datatables') {
              i18n.msgDatatablesStore = JSON.parse(data);
            } else {
              i18n.msgAdditionStores[additionname] = JSON.parse(data);
            }
          },
          function() {
            console.log("Error: language file " + additionname + " not found, using fallback 'en'!");
            getRequest(
              '/locale/' + additionname + '_en' + (additionname == 'datatables' ? '.lang' : '.json'),
              function(data) {
                if (additionname == 'datatables') {
                  i18n.msgDatatablesStore = JSON.parse(data);
                } else {
                  i18n.msgAdditionStores[additionname] = JSON.parse(data);
                }
              },
              function() {}
            );
          }
        );
      }
    },
    setSupportedLanguages: function(data) {
      this.lang_names = data.names;
      this.lang_codes = data.codes;
      this.lang_additions = data.additions;
    },
    initMsgStore: function(options) {
      var lang = "en";
      i18n.setLanguage(lang);
    },
    initLangAdditions: function() {
      // load ise supported languages
      getRequest(
        '/locale/languages.json',
        function(data) {
          i18n.setSupportedLanguages(JSON.parse(data));
        },
        function() {
          console.log('Error: supported languages file /locale/languages.json not found or invalid!');
        }
      );
    },
    userSelected: function(lang) {
      this.setLanguage(lang);
    },
    init: function(options) {

      var localMsgStore = "";
      var localMsgStoreBackup = "";
      var localDatatablesStore = "";
      this.lang_names = ["English"];
      this.lang_codes = ["en"];
      this.lang_additions = [];
      this.initLangAdditions();
      this.initMsgStore(options);
    }
  };
  /* Expose i18n to the global object */
  window.i18n = i18n;

})(window);

function getRequest(url, onloadCallback, onErrorCallback) {
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", url, false);
  xhttp.setRequestHeader("Content-type", "application/json");
  //xhttp.timeout = 2000;
  xhttp.onload = function() {
    if (xhttp.readyState == 4)
      if (xhttp.status == 200 || xhttp.status == 201) {
        onloadCallback(xhttp.response);
      } else onErrorCallback();
  }
  xhttp.onerror = function(e) {
    onErrorCallback();
  }
  xhttp.send();
}
