//Run when the document loads AND we have the config loaded.
(function(){
  "use strict";
  var config;
  Promise.all([
    new Promise(function(resolve, reject){
      $.ajax('config.json').done(function(data){
        config = data;
        resolve();
      }).fail(function(){
        console.error("Failed to get config.");
        ga('send', 'event', 'error', 'config');
        reject();
      });
    }),
    new Promise(function(resolve, reject){
      var timeout = setTimeout(function(){
        console.error("Document never loaded? Something bad has happened!");
        reject();
      }, 10000);
      $(function () {
        clearTimeout(timeout);
        resolve();
      });
    })
  ]).then(function(){

    var getParameterByName = function(name){
          name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
              var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
                  results = regex.exec(location.search);
            return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    //Overwrite config if present. Any failure will just cause this to be skipped.
    try{
      var configParam = JSON.parse(getParameterByName('config'));
      config = jQuery.extend(true, config, configParam);
    } catch(e){
      console.warn("Failure in config overwrite, skipping.", e);
    }

    new Atmos(config);
  }, function(){
    console.error("Failed to initialize!");
    ga('send', 'event', 'error', 'init');
  });
})();

var Atmos = (function(){
  "use strict";

  var closeButton = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';

  var guid = function(){
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = (d + Math.random()*16)%16 | 0;
      d = Math.floor(d/16);
      return (c=='x' ? r : (r&0x3|0x8)).toString(16);
    });
    return uuid;
  }

  /**
   * Atmos
   * @version 2.0
   *
   * Configures an Atmos object. This manages the atmos interface.
   *
   * @constructor
   * @param {string} catalog - NDN path
   * @param {Object} config - Object of configuration options for a Face.
   */
  var Atmos = function(config){

    //Internal variables.
    this.results = [];
    this.resultCount = Infinity;
    this.name = null;
    this.page = 0;
    this.resultsPerPage = 25;
    this.retrievedSegments = 0;

    //Config/init
    this.config = config;

    this.catalog = config['global']['catalogPrefix'];

    this.face = new Face(config['global']['faceConfig']);

    //Easy access dom variables
    this.categories = $('#side-menu');
    this.resultTable = $('#resultTable');
    this.filters = $('#filters');
    this.searchInput = $('#search');
    this.searchBar = $('#searchBar');
    this.searchButton = $('#searchButton');
    this.resultMenu = $('.resultMenu');
    this.alerts = $('#alerts');
    this.requestForm = $('#requestForm');

    var scope = this;

    $('.requestSelectedButton').click(function(){
      ga('send', 'event', 'button', 'click', 'request');
      scope.request(scope.resultTable.find('.resultSelector:checked:not([disabled])').parent().parent());
    });

    this.filterSetup();

    //Init autocomplete
    this.searchInput.autoComplete(function(field, callback){
      ga('send', 'event', 'search', 'autocomplete');
      scope.autoComplete(field, function(data){
        var list = data.next;
        var last = data.lastComponent === true;
        callback(list.map(function(element){
          return field + element + (last?"/":""); //Don't add trailing slash for last component.
        }));
      });
    });

    //Handle search
    this.searchBar.submit(function(e){
      ga('send', 'event', 'search', 'submit');
      e.preventDefault();
      if (scope.searchInput.val().length === 0){
        if (!scope.searchBar.hasClass('has-error')){
          scope.searchBar.addClass('has-error').append('<span class="help-block">Search path is required!</span>');
        }
        return;
      } else {
        scope.searchBar.removeClass('has-error').find('.help-block').fadeOut(function(){$(this).remove()});
      }
      scope.pathSearch();
    });

    this.searchButton.click(function(){
      console.log("Search Button Pressed");
      ga('send', 'event', 'button', 'click', 'search');
      scope.search();
    });

    //Result navigation handlers
    this.resultMenu.find('.next').click(function(){
      ga('send', 'event', 'button', 'click', 'next');
      if (!$(this).hasClass('disabled')){
        scope.getResults(scope.page + 1);
      }
    });
    this.resultMenu.find('.previous').click(function(){
      ga('send', 'event', 'button', 'click', 'previous');
      if (!$(this).hasClass('disabled')){
        scope.getResults(scope.page - 1);
      }
    });
    this.resultMenu.find('.clearResults').click(function(){
      ga('send', 'event', 'button', 'click', 'resultClear');
      scope.clearResults();
      $('#results').fadeOut(function(){
        $(this).addClass('hidden');
      });
    });

    //Change the number of results per page handler
    var rpps = $('.resultsPerPageSelector').click(function(){

      var t = $(this);

      if (t.hasClass('active')){
        return;
      }

      rpps.find('.active').removeClass('active');
      t.addClass('active');
      scope.resultsPerPage = Number(t.text());
      scope.getResults(0); //Force return to page 1;

    });

    //Init tree search
    $('#treeSearch div').treeExplorer(function(path, callback){
      console.log("Tree Explorer request", path);
      ga('send', 'event', 'tree', 'request');
      scope.autoComplete(path, function(data){
        var list = data.next;
        var last = (data.lastComponent === true);

        if (last) {
          console.log("Redirecting last element request to a search.");
          scope.clearResults();
          scope.query(scope.catalog, {'??': path},
          function(interest, data){
            console.log("Search response", interest, data);
            scope.name = data.getContent().toString().replace(/[\n\0]+/g, '');
            scope.getResults(0);
          }, function(interest){
            console.warn("Failed to retrieve final component.", interest, path);
            scope.createAlert("Failed to request final component. " + path + " See console for details.");
          });
          return; //Don't call the callback
        }

        console.log("Autocomplete response", list);
        callback(list.map(function(element){
          return (path == "/"?"/":"") + element + "/";
        }));
      })
    });

    $('#treeSearch').on('click', '.treeSearch', function(){
      var t = $(this);

      scope.clearResults();

      var path = t.parent().parent().attr('id');

      console.log("Tree search:", path);

      scope.query(scope.catalog, {'??': path},
      function(interest, data){ //Success
        console.log("Tree search response", interest, data);

        scope.name = data.getContent().toString().replace(/[\n\0]+/g,'');

        scope.getResults(0);
      },
      function(interest){ //Failure
        console.warn("Request failed! Timeout", interest);
        scope.createAlert("Request timed out.\""+ interest.getName().toUri() + "\" See console for details.");
      });

    });

    this.setupRequestForm();

    this.resultTable.popover({
      selector : ".metaDataLink",
      content: function(){
        return scope.getMetaData(this);
      },
      title: "Metadata",
      html: true,
      trigger: 'click',
      placement: 'bottom'
    });

    this.resultTable.on('click', '.metaDataLink', function(e){
      //This prevents the page from scrolling when you click on a name.
      e.preventDefault();
    });

    this.resultTable.on('click', '.subsetButton', function(){
      var metaData = $(this).siblings('pre').text();
      var exp = /netcdf ([\w-]+)/;
      var match = exp.exec(metaData);
      var filename = match[0].replace(/netcdf /,'') + '.nc';
      scope.request(null, filename);
    });

  }

  Atmos.prototype.clearResults = function(){
    this.results = []; //Drop any old results.
    this.retrievedSegments = 0;
    this.resultCount = Infinity;
    this.page = 0;
    this.resultTable.empty();
  }

  Atmos.prototype.pathSearch = function(){
    var value = this.searchInput.val();

    this.clearResults();

    var scope = this;

    this.query(this.catalog, {"??": value},
    function(interest, data){
      console.log("Query response:", interest, data);

      scope.name = data.getContent().toString().replace(/[\n\0]/g,"");

      scope.getResults(0);

    },
    function(interest){
      console.warn("Request failed! Timeout", interest);
      scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
    });

  }

  Atmos.prototype.search = function(){

    var filters = this.getFilters();

    console.log("Search started!", this.searchInput.val(), filters);

    console.log("Initiating query");

    this.clearResults();

    var scope = this;

    this.query(this.catalog, filters,
    function(interest, data){ //Response function
      console.log("Query Response:", interest, data);

      scope.name = data.getContent().toString().replace(/[\n\0]/g,"");

      scope.getResults(0);

    }, function(interest){ //Timeout function
      console.warn("Request failed after 3 attempts!", interest);
      scope.createAlert("Request failed after 3 attempts. \"" + interest.getName().toUri() + "\" See console for details.");
    });

  }

  Atmos.prototype.autoComplete = function(field, callback){

    var scope = this;

    this.query(this.catalog, {"?": field},
    function(interest, data){

      var name = new Name(data.getContent().toString().replace(/[\n\0]/g,""));

      var interest = new Interest(name);
      interest.setInterestLifetimeMilliseconds(1500);
      interest.setMustBeFresh(true);

      var count = 3;

      var run = function(){

        if (--count === 0){
          console.warn("Interest timed out!", interest);
          scope.createAlert("Request failed after 3 attempts. \"" + interest.getName().toUri() + "\" See console for details.");
          return;
        }

        scope.face.expressInterest(interest,
        function(interest, data){

          if (data.getContent().length !== 0){
            callback(JSON.parse(data.getContent().toString().replace(/[\n\0]/g, "")));
          } else {
            callback([]);
          }

        }, run);
      }

      run();

    }, function(interest){
      console.error("Request failed! Timeout", interest);
      scope.createAlert("Request failed after 3 attempts. \"" + interest.getName().toUri() + "\" See console for details.");
    });

  }

  Atmos.prototype.showResults = function(resultIndex) {

    var results = this.results.slice(this.resultsPerPage * resultIndex, this.resultsPerPage * (resultIndex + 1));

    var resultDOM = $(
      results.reduce(function(prev, current){
        prev.push('<tr><td><input class="resultSelector" type="checkbox"></td><td class="popover-container"><a href="#" class="metaDataLink">');
        prev.push(current);
        prev.push('</a></td></tr>');
        return prev;
      }, ['<tr><th><input id="resultSelectAll" type="checkbox" title="Select All"> Select</th><th>Name</th></tr>']).join('')
    );

    resultDOM.find('#resultSelectAll').click(function(){
      if ($(this).is(':checked')){
        resultDOM.find('.resultSelector:not([disabled])').prop('checked', true);
      } else {
        resultDOM.find('.resultSelector:not([disabled])').prop('checked', false);
      }
    });

    this.resultTable.hide().empty().append(resultDOM).slideDown('slow');

    this.resultMenu.find('.pageNumber').text(resultIndex + 1);
    this.resultMenu.find('.pageLength').text(this.resultsPerPage * resultIndex + results.length);

    if (this.resultsPerPage * (resultIndex + 1) >= this.resultCount) {
      this.resultMenu.find('.next').addClass('disabled');
    } else if (resultIndex === 0){
      this.resultMenu.find('.next').removeClass('disabled');
    }

    if (resultIndex === 0){
      this.resultMenu.find('.previous').addClass('disabled');
    } else if (resultIndex === 1) {
      this.resultMenu.find('.previous').removeClass('disabled');
    }

    $.scrollTo("#results", 500, {interrupt: true});

  }

  Atmos.prototype.getResults = function(index){

    if ($('#results').hasClass('hidden')){
      $('#results').removeClass('hidden').slideDown();
    }

    if ((this.results.length === this.resultCount) || (this.resultsPerPage * (index + 1) < this.results.length)){
      //console.log("We already have index", index);
      this.page = index;
      this.showResults(index);
      return;
    }

    if (this.name === null) {
      console.error("This shouldn't be reached! We are getting results before a search has occured!");
      throw new Error("Illegal State");
    }

    var first = new Name(this.name).appendSegment(this.retrievedSegments++);

    console.log("Requesting data index: (", this.retrievedSegments - 1, ") at ", first.toUri());

    var scope = this;

    var interest = new Interest(first)
    interest.setInterestLifetimeMilliseconds(5000);
    interest.setMustBeFresh(true);

    this.face.expressInterest(interest,
      function(interest, data){ //Response

        if (data.getContent().length === 0){
          scope.resultMenu.find('.totalResults').text(0);
          scope.resultMenu.find('.pageNumber').text(0);
          scope.resultMenu.find('.pageLength').text(0);
          console.log("Empty response.");
          return;
        }

        var content = JSON.parse(data.getContent().toString().replace(/[\n\0]/g,""));

        if (!content.results){
          scope.resultMenu.find('.totalResults').text(0);
          scope.resultMenu.find('.pageNumber').text(0);
          scope.resultMenu.find('.pageLength').text(0);
          console.log("No results were found!");
          return;
        }

        scope.results = scope.results.concat(content.results);

        scope.resultCount = content.resultCount;

        scope.resultMenu.find('.totalResults').text(scope.resultCount);

        scope.page = index;

        scope.getResults(index); //Keep calling this until we have enough data.

      },
      function(interest){ //Timeout
        console.error("Failed to retrieve results: timeout", interest);
        scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
      }
    );

  }

  Atmos.prototype.query = function(prefix, parameters, callback, timeout) {

    var queryPrefix = new Name(prefix);
    queryPrefix.append("query");

    var jsonString = JSON.stringify(parameters);
    queryPrefix.append(jsonString);

    var queryInterest = new Interest(queryPrefix);
    queryInterest.setInterestLifetimeMilliseconds(1500);
    queryInterest.setMustBeFresh(true);

    var face = this.face;
    var retry = 3;
    var run = function(interest){
      if (--retry === 0){
        timeout(interest);
      } else {
        face.expressInterest(queryInterest, callback, run);
      }
    }
    run();

  }

  /**
   * This function returns a map of all the categories active filters.
   * @return {Object<string, string>}
   */
  Atmos.prototype.getFilters = function(){
    var filters = this.filters.children().toArray().reduce(function(prev, current){
      var data = $(current).text().split(/:/);
      prev[data[0]] = data[1];
      return prev;
    }, {}); //Collect a map<category, filter>.
    //TODO Make the return value map<category, Array<filter>>
    return filters;
  }

  /**
   * Creates a closable alert for the user.
   *
   * @param {string} message
   * @param {string} type - Override the alert type.
   */
  Atmos.prototype.createAlert = function(message, type) {

    var alert = $('<div class="alert"><div>');
    alert.addClass(type?type:'alert-info');
    alert.text(message);
    alert.append(closeButton);

    this.alerts.append(alert);
  }

  /**
   * Requests all of the names represented by the buttons in the elements list.
   *
   * @param elements {Array<jQuery>} A list of the table row elements
   * @param subsetFileName {String} If present then do a subsetting request instead.
   */
  Atmos.prototype.request = function(){

    //Pseudo globals.
    var keyChain;
    var certificateName;
    var keyAdded = false;

    return function(elements, subsetFilename){

      var names = [];
      $(elements).find('.metaDataLink').each(function(){
        var name = $(this).text();
        names.push(name);
      });

      var subset = false;

      if (!subsetFilename){
        $('#subsetting').hide();
      } else {
        $('#subsetting').show();
        subset = true;
      }

      var scope = this;
      this.requestForm.on('submit', function(e){ //This will be registered for the next submit from the form.
        e.preventDefault();

        $('#request .alert').remove();

        var variables = [];
        if (subset){
          $('#subsetVariables .row').each(function(){
            var t = $(this);
            var values = {};
            t.find('.values input').each(function(){
              var t = $(this);
              values[t.attr('name')] = t.val();
            });
            variables.push({variable: t.find('.variable').val(), values: values});
          });
        }

        //Form checking
        var dest = scope.requestForm.find('#requestDest .active');
        if (dest.length !== 1){
          var alert = $('<div class="alert alert-warning">A destination is required!' + closeButton + '<div>');
          $('#request > .panel-body').append(alert);
          return;
        }

        $('#request').modal('hide');//Initial params are ok. We can close the form.

        scope.cleanRequestForm();

        $(this).off(e); //Don't fire this again, the request must be regenerated

        //Key setup
        if (!keyAdded){
          if (!scope.config.retrieval.demoKey || !scope.config.retrieval.demoKey.pub || !scope.config.retrieval.demoKey.priv){
            scope.createAlert("This host was not configured to handle retrieval! See console for details.", 'alert-danger');
            console.error("Missing/invalid key! This must be configured in the config on the server.", scope.config.demoKey);
            return;
          }

          //FIXME base64 may or may not exist in other browsers. Need a new polyfill.
          var pub = new Buffer(base64.toByteArray(scope.config.retrieval.demoKey.pub)); //MUST be a Buffer (Buffer != Uint8Array)
          var priv = new Buffer(base64.toByteArray(scope.config.retrieval.demoKey.priv));

          var identityStorage = new MemoryIdentityStorage();
          var privateKeyStorage = new MemoryPrivateKeyStorage();
          keyChain = new KeyChain(new IdentityManager(identityStorage, privateKeyStorage),
                        new SelfVerifyPolicyManager(identityStorage));

          var keyName = new Name("/retrieve/DSK-123");
          certificateName = keyName.getSubName(0, keyName.size() - 1)
            .append("KEY").append(keyName.get(-1))
            .append("ID-CERT").append("0");

          identityStorage.addKey(keyName, KeyType.RSA, new Blob(pub, false));
          privateKeyStorage.setKeyPairForKeyName(keyName, KeyType.RSA, pub, priv);

          scope.face.setCommandSigningInfo(keyChain, certificateName);

          keyAdded = true;

        }

        //Retrieval
        var retrievePrefix = new Name("/catalog/ui/" + guid());

        scope.face.registerPrefix(retrievePrefix,
          function(prefix, interest, face, interestFilterId, filter){ //On Interest
            //This function will exist until the page exits but will likely only be used once.

            var data = new Data(interest.getName());
            var content;
            if (subset){
              content = JSON.stringify({name: subsetFilename, subset: variables});
            } else {
              content = JSON.stringify(names);
            }
            //Blob breaks the data! Don't use it
            data.setContent(content); //TODO Packetize this.
            keyChain.sign(data, certificateName);

            try {
              face.putData(data);
              console.log("Responded for", interest.getName().toUri(), data);
              scope.createAlert("Data retrieval has initiated.", "alert-success");
            } catch (e) {
              console.error("Failed to respond to", interest.getName().toUri(), data);
              scope.createAlert("Data retrieval failed.");
            }

          }, function(prefix){ //On fail
            scope.createAlert("Failed to register the retrieval URI! See console for details.", "alert-danger");
            console.error("Failed to register URI:", prefix.toUri(), prefix);
          }, function(prefix, registeredPrefixId){ //On success
            var name = new Name(dest.text());
            name.append(prefix);
            var interest = new Interest(name);
            interest.setInterestLifetimeMilliseconds(1500);
            var count = 3;
            var run = function(i2){

              if (--count === 0) {
                console.error("Request for", name.toUri(), "timed out (3 times).", i2);
                scope.createAlert("Request for " + name.toUri() + " timed out after 3 attempts. This means that the retrieve failed! See console for more details.");
                return;
              }

              scope.face.expressInterest(interest,
                function(interest, data){ //Success
                  console.log("Request for", name.toUri(), "succeeded.", interest, data);
                },
                run
              );
            }
            run();
          }
        );

      });
      $('#request').modal(); //This forces the form to be the only option.

    }
  }();

  Atmos.prototype.filterSetup = function() {
    //Filter setup

    var prefix = new Name(this.catalog).append("filters-initialization");

    var scope = this;

    this.getAll(prefix, function(data) { //Success
      var raw = JSON.parse(data.replace(/[\n\0]/g, '')); //Remove null byte and parse

      console.log("Filter categories:", raw);

      $.each(raw, function(index, object){ //Unpack list of objects
        $.each(object, function(category, searchOptions) { //Unpack category from object (We don't know what it is called)
          //Create the category
          var e = $('<li><a href="#">' + category.replace(/_/g, " ") + '</a><ul class="subnav nav nav-pills nav-stacked"></ul></li>');

          var sub = e.find('ul.subnav');
          $.each(searchOptions, function(index, name){
            //Create the filter list inside the category
            var item = $('<li><a href="#">' + name + '</a></li>');
            sub.append(item);
            item.click(function(){ //Click on the side menu filters
              if (item.hasClass('active')){ //Does the filter already exist?
                item.removeClass('active');
                scope.filters.find(':contains(' + category + ':' + name + ')').remove();
              } else { //Add a filter
                item.addClass('active');
                var filter = $('<span class="label label-default"></span>');
                filter.text(category + ':' + name);

                scope.filters.append(filter);

                filter.click(function(){ //Click on a filter
                  filter.remove();
                  item.removeClass('active');
                });
              }

            });
          });

          //Toggle the menus. (Only respond when the immediate tab is clicked.)
          e.find('> a').click(function(){
            scope.categories.find('.subnav').slideUp();
            var t = $(this).siblings('.subnav');
            if ( !t.is(':visible') ){ //If the sub menu is not visible
              t.slideDown(function(){
                t.triggerHandler('focus');
              }); //Make it visible and look at it.
            }
          });

          scope.categories.append(e);

        });
      });

    }, function(interest){ //Timeout
      scope.createAlert("Failed to initialize the filters!", "alert-danger");
      console.error("Failed to initialize filters!", interest);
      ga('send', 'event', 'error', 'filters');
    });

  }

  /**
   * This function retrieves all segments in order until it knows it has reached the last one.
   * It then returns the final joined result.
   * 
   * @param prefix {String|Name} The ndn name we are retrieving.
   * @param callback {function(String)} if successful, will call the callback with a string of data.
   * @param failure {function(Interest)} if unsuccessful, will call failure with the last failed interest.
   * @param stop {boolean} stop if no finalBlock.
   */
  Atmos.prototype.getAll = function(prefix, callback, failure, stop){

    var scope = this;
    var d = [];

    var count = 3;
    var retry = function(interest){
      if (count === 0){
        console.log("Failed to 'getAll' after 3 attempts", interest.toUri(), interest);
        failure(interest);
      } else {
        count--;
        request(interest.getName().get(-1).toSegment());
      }
    }

    var request = function(segment){

      var name = new Name(prefix);
      name.appendSegment(segment);

      var interest = new Interest(name);
      interest.setInterestLifetimeMilliseconds(1500);
      interest.setMustBeFresh(true); //Is this needed?

      scope.face.expressInterest(interest, handleData, retry);

    }

    var handleData = function(interest, data){

      d.push(data.getContent().toString());

      var hasFinalBlock = data.getMetaInfo().getFinalBlockId().value.length === 0;
      var finalBlockStop = hasFinalBlock && stop;

      if (finalBlockStop ||
      (!hasFinalBlock && interest.getName().get(-1).toSegment() == data.getMetaInfo().getFinalBlockId().toSegment())){
        callback(d.join(""));
      } else {
        request(interest.getName().get(-1).toSegment() + 1);
      }

    }

    request(0);

  }

  Atmos.prototype.cleanRequestForm = function(){
    $('#requestDest').prev().removeClass('btn-success').addClass('btn-default');
    $('#requestDropText').text('Destination');
    $('#requestDest .active').removeClass('active');
    $('#subsetMenu').attr('class', 'collapse');
    $('#subsetVariables').empty();
    $('#request .alert').alert('close').remove();
  }

  Atmos.prototype.setupRequestForm = function(){

    var scope = this;

    this.requestForm.find('#requestCancel').click(function(){
      $('#request').unbind('submit') //Removes all event handlers.
      .modal('hide'); //Hides the form.
      scope.cleanRequestForm();
    });

    var dests = $(this.config['retrieval']['destinations'].reduce(function(prev, current){
      prev.push('<li><a href="#">');
      prev.push(current);
      prev.push("</a></li>");
      return prev;
    }, []).join(""));

    this.requestForm.find('#requestDest').append(dests)
    .on('click', 'a', function(e){
      $('#requestDest .active').removeClass('active');
      var t = $(this);
      t.parent().addClass('active');
      $('#requestDropText').text(t.text());
      $('#requestDest').prev().removeClass('btn-default').addClass('btn-success');
    });

    var addVariable = function(selector){
      var ele = $(selector).clone().attr('id','');
      ele.find('.close').click(function(){
        ele.remove();
      });
      $('#subsetVariables').append(ele);
    };

    $('#subsetAddVariableBtn').click(function(){
      addVariable('#customTemplate');
    });
    $('#subsetAddTimeVariable').click(function(){
      addVariable('#timeTemplate');
    });
    $('#subsetAddLocVariable').click(function(){
      addVariable('#locationTemplate');
    });

  }

  Atmos.prototype.getMetaData = (function(){

    var cache = {};

    return function(element) {
      var name = $(element).text();

      ga('send', 'event', 'request', 'metaData');

      var subsetButton = '<button class="btn btn-default subsetButton" type="button">Subset</button>';

      if (cache[name]) {
        return [subsetButton, '<pre class="metaData">', cache[name], '</pre>'].join('');
      }

      var prefix = new Name(name).append("metadata");
      var id = guid(); //We need an id because the return MUST be a string.
      var ret = '<div id="' + id + '"><span class="fa fa-spinner fa-spin"></span></div>';

      this.getAll(prefix, function(data){
        var el = $('<pre class="metaData"></pre>');
        el.text(data);
        var container = $('<div></div>');
        container.append($(subsetButton));
        container.append(el);
        $('#' + id).empty().append(container);
        cache[name] = data;
      }, function(interest){
        $('#' + id).text("The metadata is unavailable for this name.");
        console.log("Data is unavailable for " + name);
      });

      return ret;

    }
  })();

  return Atmos;

})();
