//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.catalogPrefix = new Name(this.catalog);

    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 = interest.getName();
            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 = interest.getName();

        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.getName();

      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 = interest.getName();

      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 = interest.getName();

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

      async.retry(4, function(done){
        scope.face.expressInterest(interest,
        function(interest, data){

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

        }, function(){
          done("Failed attempt to request data.")
        });
      }, function(err, results){
        if (err){
          console.warn("Interest timed out!", interest);
          scope.createAlert("Request failed after 3 attempts. \"" + interest.getName().toUri() + "\" See console for details.");
        }
      });

    }, 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){
    var scope = this;

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

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

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

    var interestName = new Name(scope.name);

    // Interest name should be /<catalog-prefix>/query/<query-param>/<version>/<#seq>
    if (scope.name.size() === (scope.catalogPrefix.size() + 3)) {
      interestName = interestName.appendSegment(scope.retrievedSegments++);
      console.log("Requesting data index: (", scope.retrievedSegments - 1, ") at ", interestName.toUri());
    }

    var interest = new Interest(interestName);

    interest.setInterestLifetimeMilliseconds(1500);
    interest.setMustBeFresh(true);

    async.retry(4, function(done){
      scope.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.");
            scope.resultTable.html("<tr><td>Empty response. This usually means no results.</td></tr>");
            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!");
            scope.resultTable.html("<tr><td>No Results</td></tr>");
            return;
          }

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

          scope.resultCount = content.resultCount;

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

          scope.page = index;

          // reset scope.name
          scope.name = new Name(data.getName().getPrefix(scope.catalogPrefix.size() + 3));

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

          done();

        },
        function(interest){ //Timeout
          done("Failed to request results.");
        }
      );
    }, function(err){
      if (err){
        console.error("Failed to retrieve results: timeout", interest);
        scope.createAlert("Request failed after 3 attempts. \"" + 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;

    async.retry(4, function(done){
      face.expressInterest(queryInterest, function(interest, data){
        callback(interest, data);
        done();
       }, function(interest){
         done("Failed attempt to query results", interest);
       });
    }, function(err, interest){
      if (err){
        timeout(interest);
      }
    });

  };

  /**
   * 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);

            async.retry(4, function(done){
              scope.face.expressInterest(interest,
                function(interest, data){ //Success
                  console.log("Request for", name.toUri(), "succeeded.", interest, data);
                  done();
                },
                function(){
                  done("Failed to request from retrieve agent.");
                }
              );
            }, function(err){
              if (err){
                console.error("Request for", name.toUri(), "timed out (3 times).", interest);
                scope.createAlert("Request for " + name.toUri() + " timed out after 3 attempts. This means that the retrieve failed! See console for more details.");
              }
            });

          }
        );

      });
      $('#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 name = new Name(prefix);
    var segment = 0;

    var request = function(){

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

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

      async.retry(4, function(done){
        scope.face.expressInterest(interest,
          function(interest, data){
            handleData(interest, data);
            done();
          }, function(){
            done("Failed to get segment.");
          }
        );
      }, function(err){
        if (err){
          console.log("Failed after 3 attempts:", err);
        }
      });

    };

    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 {
        segment++;
        request();
      }

    };

    request();

  };

  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;

})();
