/*
 * EdGEL: The University of Edinburgh Experience Language.
 * Cookie Consent Settings JS File.
 */
/**
if (typeof jQuery === 'undefined') {
  throw new Error('EdGEL\'s JavaScript requires jQuery')
}

var EdGel = EdGel || {};

(function (global, $) {
  'use strict';

  global.EdGel.cookieSettings = global.EdGel.cookieSettings || (function () {
    var loaded = false;
    var version = 2;
    var permissions = {
        necessary: {
          name: 'necessary',
          disabled: true,
          checked: true,
          label: 'These cookies are essential in order to enable you to move ' +
            'around the website and so cannot be disabled. This includes ' +
            'anonymous analytics data.',
          link: 'https://www.ed.ac.uk/about/website/privacy/necessary-cookies'
        },
        performance: {
          name: 'performance',
          disabled: false,
          checked: true,
          label: 'Allow performance cookies for tools that help us improve ' +
            'the experience of using our site.',
          link: 'https://www.ed.ac.uk/about/website/privacy/performance-cookies'
        },
        advertising: {
          name: 'advertising',
          disabled: false,
          checked: true,
          label: 'Allow us to personalise ads, such as providing reminders ' +
            'of Open Days, by sharing information about your site use with ' +
            'partners we work with.',
          link: 'https://www.ed.ac.uk/about/website/privacy/advertising-cookies'
        }
      };
    var _values = {};
    var _noPermission = true;
    var subscribers = [];
    var bootstrapped = false;

    function getValues() {
      var values = {}

      for (var pref in permissions) {
        if (permissions[pref].disabled) {
          values[pref] = permissions[pref].checked
        }
        else if (_values.hasOwnProperty(pref)) {
          values[pref] = _values[pref]
        }
        else {
          values[pref] = permissions[pref].checked
        }
      }

      return values
    }

    function reset() {
      loaded = false;
      _values = {}
      _noPermission = true;
    }

    function load() {
      reset();

      var stored = readPrefs();

      _values = stored;
      loaded = !_noPermission;

      // If we are missing any immutable (disabled checkbox) values, we
      // don't have a valid load.
      for (var perm in permissions) {
        if (permissions[perm].disabled && !stored.hasOwnProperty(perm)) {
          loaded = false;
        }
      }
    }

    function readPrefs() {
      var decodedCookie = decodeURIComponent(document.cookie);
      var allCookies = decodedCookie.split(';');
      var json = '';
      for (var i = 0; i < allCookies.length; i++) {
        var curr = allCookies[i].trim();

        if (curr.indexOf('_uoeCookiePrefs=') == 0) {
          json = curr.substring('_uoeCookiePrefs='.length, curr.length);
        }
      }

      var parsed = {};
      var requiresUpdate = false;
      if (json) {
        try {
          // If we have raw JSON string encode this since the value can cause
          // problems with other systems: I180531-0649
          if (json.indexOf('{') == 0) {
            requiresUpdate = true;
          }
          else {
            json = global.atob(json);
          }
          parsed = JSON.parse(json);
          if (parsed.hasOwnProperty('version') && parsed.version >= version) {
            _noPermission = false;
          }
        }
        catch (e) {
          parsed = {};
        }
      }

      if (requiresUpdate) {
        writeCookie(parsed);
      }

      return parsed;
    }

    function savePrefs() {
      // Iterate over all checkboxes in #cookiePrefs.
      $('#cookiePrefs input[type="checkbox"]').each(function () {
        _values[$(this).attr('name')] = $(this).is(':checked')
      });

      // Don't lose any values from custom permissions on external sites.
      var storePrefs = readPrefs();
      var values = getValues();

      // Update preferences for this site.
      for (var pref in values) {
        storePrefs[pref] = values[pref]
      }

      // Store version with preferences so they can be expired if uses change.
      storePrefs.version = version;

      writeCookie(storePrefs);
    }

    function writeCookie(cValue) {
      cValue = JSON.stringify(cValue);
      cValue = global.btoa(cValue);

      var d = new Date();
      d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000));
      var expires = 'expires=' + d.toUTCString();

      var cDomain = '.ed.ac.uk';
      document.cookie = '_uoeCookiePrefs=' + cValue + ';' + expires + ';domain=' + cDomain + ';path=/';

      // Notify subscribers that a change has happened.
      for (var i = 0; i < subscribers.length; i++) {
        subscribers[i]()
      }
    }

    function editPrefs() {
      var preferences = permissions;
      var values = getValues();
      var cookiePrefsOptionsView = [];

      for (var pref in preferences) {
        if (values.hasOwnProperty(pref)) {
          preferences[pref].checked = values[pref]
        }
        cookiePrefsOptionsView.push(preferences[pref])
      }

      var cookiePrefsFormView = {
        settings: cookiePrefsOptionsView,
        heading: 'Change my cookie settings for the University of Edinburgh website'
      };

      $('#cookie-jar').html(nunjucks.render('uoe-cookies-preferences.njk', cookiePrefsFormView));
      $('#cookie-jar').slideDown('slow');
      $('html, body').animate({ scrollTop: 0 }, 400);
      $('#cookie-lid').hide('slow');
    }

    return {
      allowed: function (permission) {
        // Only return default allowed values if there has been implicit
        // acceptance of the default settings.
        if (_noPermission) {
          return false;
        }

        var prefs = getValues();
        return prefs[permission];
      },

      allowedList: function () {
        // Only return default allowed values if there has been implicit
        // acceptance of the default settings.
        if (_noPermission) {
          return '';
        }

        var prefs = getValues();
        var allowed = [];

        for (var pref in prefs) {
          if (prefs[pref]) {
            allowed.push(pref);
          }
        }

        return allowed.sort().join();
      },

      bannerRequired: function () {
        return !(this.hasSavedSettings());
      },

      hasSavedSettings: function () {
        return loaded;
      },

      cookieInfoView: {
        link: 'https://www.ed.ac.uk/about/website/privacy',
        heading: 'Cookies on the University of Edinburgh website',
        text: [
          'We use cookies to ensure the best experience on our website, ' +
          'analyse site traffic and understand user behaviour. We also use ' +
          'cookies to share information with our partners in an effort to ' +
          'ensure you only receive relevant advertising from us.',
          'If you continue without changing your settings, we\'ll assume ' +
          'that you are happy to receive all cookies on our website. ' +
          'However, you can change your settings at any time. '
        ]
      },

      bootstrap: function () {
        if (!bootstrapped) {
          load();

          // Attach callbacks to banner buttons.
          var _this = this;
          $('html').on('click', 'button.cookie-btn-save', function () {
            savePrefs();
            // Re-open the banner; it will close to the lid if preference
            // values are complete.
            _this.openBanner(true);
            return false;
          });
          $('html').on('click', 'button.cookie-btn-change', function () {
            editPrefs();
            return false;
          });
          $('html').on('click', 'button.cookie-btn-cancel', function () {
            // Re-open the banner; it will close to the lid if preference
            // values are complete.
            _this.openBanner(true);
            return false;
          });
          $('html').on('click', 'a:not(.cookie-link):not(.cookie-btn), button:not(.cookie-btn), input[type=submit]', function () {
            // The user has clicked on an interactive element, so assume consent
            // and save the settings.
            savePrefs();
            // Re-open the banner; it will close to the lid if preference
            // values are complete.
            _this.openBanner(true);
            // Allow other click events to continue as normal.
          });

          bootstrapped = true;
        }
      },

      openBanner: function (animate) {
        // Reload preferences from _uoeCookiePrefs cookie, if present.
        load();

        if (this.bannerRequired()) {
          $('#cookie-jar').html(nunjucks.render('uoe-cookies-banner.njk', this.cookieInfoView));
          if (animate) {
            $('#cookie-jar').slideDown('slow');
            $('#cookie-lid').hide('slow');
          }
          else {
            $('#cookie-jar').show(0);
            $('#cookie-lid').hide(0);
          }
        }
        else {
          // Show the floating button that allows access to change settings.
          $('#cookie-lid').html(nunjucks.render('uoe-cookies-lid.njk', this.cookieInfoView));
          if (animate) {
            $('#cookie-lid').show('slow');
            $('#cookie-jar').slideUp('slow');
          }
          else {
            $('#cookie-lid').show(0);
            $('#cookie-jar').hide(0);
          }
        }
      },

      // Add a subscriber function to be called whenever settings are changed
      // or successfully loaded.
      subscribe: function (fn) {
        subscribers.push(fn);

        // Do an initial call to the subscriber function so it can initialise.
        fn()
      },

      // Allow extra departmental permissions to be added to the banner.
      addPermission: function (perm) {
        // Validate permission object.
        var stringProps = ['name', 'label', 'link']
        var booleanProps = ['checked', 'disabled']
        var allProps = stringProps.concat(booleanProps)

        for (var i = 0; i < stringProps.length; i++) {
          if (!perm.hasOwnProperty(stringProps[i])
              || typeof perm[stringProps[i]] !== 'string'
              || !perm[stringProps[i]]) {
            throw 'The permission object must have a non-empty string ' +
              'value for the ' + stringProps[i] + ' property.'
          }
        }
        for (i = 0; i < booleanProps.length; i++) {
          if (!perm.hasOwnProperty(booleanProps[i])
              || typeof perm[booleanProps[i]] !== 'boolean') {
            throw 'The permission object must have a boolean value for the ' +
              booleanProps[i] + ' property.'
          }
        }
        // Check for extra properties.  Since we're storing this, we don't
        // want extra unnecessary data.
        for (var prop in perm) {
          if (allProps.indexOf(prop) === -1) {
            throw 'Unknown property ' + prop + ' in permission object.'
          }
        }

        // If the permission already exists don't allow it to be changed.
        if (permissions.hasOwnProperty(perm.name)) {
          throw 'The permission ' + perm.name + ' has already been defined.'
        }

        // Permission has been validated, so add it to cookiePrefs.
        permissions[perm.name] = perm;
      }
    }
  })();

  // Preload cookie settings ready for subscribers.
  global.EdGel.cookieSettings.bootstrap();

  $(function () {
    // Add a div for the main banner for cookie settings.
    var $cookieJar = $('<div id="cookie-jar" class="cookie-jar" />');
    $cookieJar.prependTo($('body')).hide(0);

    // Add a div for the small panel to allow changing cookie options.
    var $cookieLid = $('<div id="cookie-lid" class="cookie-lid" />');
    $cookieLid.appendTo($('body')).hide(0);

    EdGel.cookieSettings.openBanner(false);
  });

})(this, jQuery);
*/
