//{@ @todo: this need to be configured before the document load
var catalog = "/catalog/myUniqueName";
var config = {
  host: "ndn-atmos.atmos.colostate.edu",
  port: 9696
};

// @}

var atmos = {}; //Comment this out if you don't want debug access.

//Run when the document loads.
$(function () {
  
  //remove "atmos =" if you don't want debug access
  atmos = new Atmos(catalog, config);
  
});

/*
  
*/

/**
 * 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. 
 */
function Atmos(catalog, config){
  "use strict";
  //Internal variables.
  this.results = []
  this.resultCount = 0;
  this.page = 1;
  this.totalPages = 1;
  this.selectedSearch = {};
  this.dropdown = [];
  this.state = {};
  this.currentViewIndex = 0;

  this.catalog = catalog;

  this.face = new Face(config);
  this.categories = $('#side-menu');
  this.resultTable = $('#resultTable');
  this.filters = $('#filters');

  var scope = this;

  this.resultTable.on('click', '.interest-button', function(){
    var button = $(this);

    var name = button.parent().prev().text();
    var interest = new Interest(new Name('/retrieve' + name));
    scope.face.expressInterest(interest, function(){
      var message = $('<div class="success"><span class="glyphicon glyphicon-ok"></span> Success!</div>');
      message.insertAfter(button);
      message.fadeOut(5000);
    }, function(){
      var message = $('<div class="fail"><span class="glyphicon glyphicon-remove"></span> Failed!</div>');
      message.insertAfter(button);
      message.fadeOut(5000);
    });

  });

  $.getJSON("search_catagories.json").done(function (data) {
    $.each(data, function (pageSection, contents) {
      if (pageSection == "SearchCatagories") {
        $.each(contents, function (search, searchOptions) {
          var e = $('<li><a href="#">' + search.replace(/\_/g, " ") + '</a><ul class="subnav nav nav-pills nav-stacked"></ul></li>');

          var sub = e.find('ul.subnav');
          $.each(searchOptions, function(index, name){
            var item = $('<li><a href="#">' + name + '</a></li>');
            sub.append(item);
            item.click(function(){
              scope.addFilter(name, search);
            });
          });

          //Toggle the menus.
          e.click(function(){
            scope.categories.find('.subnav').slideUp();
            var t = $(this).find('.subnav');
            if ( !t.is(':visible')){
              t.slideDown().triggerHandler('focus'); //Cancel other animations and slide down.
            }
          });

          scope.categories.append(e);
        });
      }
    });
  });

  $('#searchBar').submit(function(e){
    e.preventDefault();
    console.log("Search started!", $('#search'));
  })

}

Atmos.prototype.onData = function(data) {
  var payloadStr = data.content.toString().split("\n")[0];

  var queryResults = JSON.parse(payloadStr);

  var scope = this;

  $.each(this.queryResults, function (queryResult, field) {

    if (queryResult == "next") {
      scope.populateAutocomplete(field);
    }

    $.each(field, function (entryCount, name) {
      scope.results.push(name);
    });
  });

  // Calculating the current page and the view
  this.totalPages = Math.ceil(this.resultCount / 20);
  this.populateResults(0);
}

Atmos.prototype.query = function(prefix, parameters, callback, pipeline) {
  this.results = [];
  this.dropdown = [];
  this.resultTable.empty();
  this.resultTable.append('<tr><th colspan="2">Results</th></tr>');

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

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

  this.state = {
      prefix: new Name(prefix),
      userOnData: callback,
      outstanding: {},
      nextSegment: 0,
      parameters: jsonString
  };

  /*if (state.hasOwnProperty("version")) {
                console.log("state already has version");
            }*/

  var queryInterest = new Interest(queryPrefix);
  queryInterest.setInterestLifetimeMilliseconds(10000);

  var scope = this;

  this.face.expressInterest(queryInterest,
    function(interest, data){
      scope.onQueryData(interest, data);
    }, function(interest){
      scope.onQueryTimeout(interest);
    }
  );

  this.state["outstanding"][queryInterest.getName().toUri()] = 0;
}

/**
 * @deprecated
 * Use applyFilters/addFilters as appropriate.
 */
Atmos.prototype.submitCatalogSearch = function(field) {
  console.warn("Use of deprecated function submitCatalogSearch! (Use applyFilters/addFilters as appropriate)");
}

Atmos.prototype.expressNextInterest = function() {
  // @todo pipelines
  var nextName = new Name(this.state["results"]);
  nextName.appendSegment(this.state["nextSegment"]);

  var nextInterest = new Interest(nextName);
  nextInterest.setInterestLifetimeMilliseconds(10000);

  var scope = this;

  this.face.expressInterest(nextInterest,
      function(interest, data){
        scope.onQueryResultsData(interest, data);
      },
      function(interest){
        scope.onQueryResultsTimeout(interest);
      });

  this.state["nextSegment"] ++;
  this.state["outstanding"][nextName.toUri()] = 0;
}

Atmos.prototype.onQueryData = function(interest, data) {
  var name = data.getName();

  delete this.state["outstanding"][interest.getName().toUri()];

  this.state["version"] = name.get(this.state["prefix"].size() + 2).toVersion();

  this.state["results"] = new Name(this.state["prefix"]).append("query-results").append(this.state['parameters']).appendVersion(this.state["version"]);

  this.expressNextInterest();
}

Atmos.prototype.onQueryResultsData = function(interest, data) {
  var name = data.getName();
  delete this.state["outstanding"][interest.getName().toUri()];
  if (!name.get(-1).equals(data.getMetaInfo().getFinalBlockId())) {
    this.expressNextInterest();
  } //else {
    //alert("found final block");
  //}

  this.state["userOnData"](data);
}

Atmos.prototype.onQueryTimeout = function(interest) {
  var uri = interest.getName().toUri();
  if (this.state["outstanding"][uri] < 1) {
    this.state["outstanding"][uri] ++;
    var scope = this;
    this.face.expressInterest(interest,
        function(interest, data){
          scope.onQueryData(interest, data);
        },
        function(interest){
          scope.onQueryTimeout(interest);
        });
  } else {
    delete this.state["outstanding"][uri];

    // We modify the autocomplete box here because we need to know
    // we have all of the entries first. Fairly hacky.
    /* TODO FIXME
    var autocompleteFullName = this.autocompleteText.value;
    for (var i = 0; i < dropdown.length; ++i) {
      if (this.dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === this.autocompleteText.value.toUpperCase || dropdown.length == 1) {
        autocompleteText.value = dropdown[i];
      }
    }
    */
  }
}

Atmos.prototype.onQueryResultsTimeout = function(interest) {
  var uri = interest.getName().toUri();
  if (this.state["outstanding"][uri] < 1) {
    this.state["outstanding"][uri] ++;
    var scope = this;
    this.face.expressInterest(interest,
        function(){
          scope.onQueryResultsData.apply(scope, arguments);
        },
        function(){
          scope.onQueryResultsTimeout.apply(scope, arguments);
        });
  } else {
    delete this.state["outstanding"][uri];
    // We modify the autocomplete box here because we need to know
    // we have all of the entries first. Fairly hacky.
    /* TODO FIXME
    var autocompleteFullName = autocompleteText.value;
    for (var i = 0; i < dropdown.length; ++i) {
      if (dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === autocompleteText.value.toUpperCase || dropdown.length == 1) {
        autocompleteText.value = dropdown[i];
      }
    }
    */
  }
}

Atmos.prototype.populateResults = function(startIndex) {
  this.resultTable.empty();
  this.resultTable.append('<tr><th colspan="2">Results</th></tr>');


  for (var i = startIndex; i < startIndex + 20 && i < this.results.length; ++i) {
    resultTable.append('<tr><td>' + this.results[i]
    + '</td><td><button class="interest-button btn btn-default btn-xs">Retrieve</button></td></tr>');
  }

  if (this.results.length <= 20) {
    this.page = 1;
  } else {
    this.page = startIndex / 20 + 1;
  }

  this.totalPages = Math.ceil(this.results.length / 20);

  //TODO Fix the page to fit the theme.
  var currentPage = $(".page");
  currentPage.empty();
  if (this.page != 1) {
    currentPage.append('<a href="#" onclick="getPage(this.id);" id="<"><</a>');
  }
  // This section of code creates the paging for the results.
  // To prevent it from having a 1000+ pages, it will only show the 5 pages before/after
  // the current page and the total pages (expect users not to really jump around a lot).
  for (var i = 1; i <= this.totalPages; ++i) {
    if (i == 1 || i == this.totalPages      // Min or max
        || (i <= this.page && i + 5 >= this.page)    // in our current page range
        || (i >= this.page && i - 5 <= this.page)) { // in our current page range
      if (i != this.page) {
        currentPage.append(' <a href="#" onclick="getPage(' + i + ');">' + i + '</a>')
        if (i == 1 && this.page > i + 5) {
          currentPage.append(' ... ');
        }
      } else {
        currentPage.append(' ' + i);
      }
    } else { // Need to skip ahead
      if (i == page + 6) {
        currentPage.append(' ... ');

        currentPage.append(' <a href="#" onclick="getPage(this.id);" id=">">></a>')
        i = this.totalPages - 1;
      }
    }
  }
  currentPage.append('  ' + this.results.length + ' results');
}

Atmos.prototype.getPage = function(clickedPage) {
  console.log(clickedPage);

  var nextPage = clickedPage;
  if (clickedPage === "<") {
    nextPage = this.page - 5;
  } else if (clickedPage === ">") {
    console.log("> enabled");

    nextPage = this.page + 5;
  }

  nextPage--; // Need to adjust for starting at 0

  if (nextPage < 0 ) {
    nextPage = 0;
    console.log("0 enabled");
  } else if (nextPage > this.totalPages - 1) {
    nextPage = this.totalPages - 1;
    console.log("total enabled");
  }

  this.populateResults(nextPage * 20);
  return false;
}


Atmos.prototype.submitAutoComplete = function() {
  /* FIXME TODO
  if (autocompleteText.value.length > 0) {
    var selection = autocompleteText.value;
    $.each(dropdown, function (i, dropdownEntry) {
      if (dropdownEntry.substr(0, dropdownEntry.length - 1) == selection) {
        selection = dropdownEntry;
      }
    });

    selectedSearch["?"] = selection;
    query(catalog, selectedSearch, onData, 1);
    delete selectedSearch["?"];
  }
  */
}

Atmos.prototype.populateAutocomplete = function(fields) {
  /* FIXME TODO
  var isAutocompleteFullName = (autocompleteText.value.charAt(autocompleteText.value.length - 1) === "/");
  var autocompleteFullName = autocompleteText.value;
  for (var i = 0; i < fields.length; ++i) {
    var fieldFullName = fields[i];
    var entry = autocompleteFullName;
    var skipahead = "";

    if (isAutocompleteFullName) {
      skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
    } else {
      if (fieldFullName.charAt(autocompleteText.value.length) === "/") {
        entry += "/";
        skipahead = fieldFullName.substr(autocompleteText.value.length + 1, fieldFullName.length);
      } else {
        skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
      }
    }
    if (skipahead.indexOf("/") != -1) {
      entry += skipahead.substr(0, skipahead.indexOf("/") + 1);
    } else {
      entry += skipahead;
    }

    var added = false;
    for (var j = 0; j < dropdown.length && !added; ++j) {
      if (dropdown[j] === entry) {
        added = true;
      } else if (dropdown[j] > entry) {
        dropdown.splice(j, 0, entry);
        added = true;
      }
    }
    if (!added) {
      dropdown.push(entry);
    }

  }
  $("#autocompleteText").autocomplete({
    source: dropdown
  });
  */
}

/**
 * Adds a filter to the list of filters.
 * There is no need to remove the filter, it is done via ui clicks.
 * 
 * @param {string} filter
 */
Atmos.prototype.addFilter = function(name, category){
  var existing = this.filters.find('span:contains(' + name + ')');
  if (existing.length){
    //If the category is clicked twice, then we delete it.
    existing.remove();
    this.applyFilters();

  } else {

    var filter = $('<span class="label label-default"></span>');
    filter.text(category + ':' + name);

    this.filters.append(filter);

    this.applyFilters();

    var scope = this;
    filter.click(function(){
      $(this).remove();
      scope.applyFilters();
    });

  }
  
}

Atmos.prototype.applyFilters = function(){
  var filters = this.filters.children().toArray().reduce(function(prev, current){
      var data = $(current).text().split(/:/);
      prev[data[0]] = data[1];
      return prev;
  }, {});
  console.log('Collected filters:', filters);
  this.query(this.catalog, filters, function(data){
    scope.onData(data);
  }, 1);
}

/**
 * @deprecated
 * Use addFilter instead.
 */
Atmos.prototype.populateCurrentSelections = function() {
  console.warn("Use of deprecated function populateCurrentSelections! (Use addFilter instead)");
  /*
  var currentSelection = $(".currentSelections");
  currentSelection.empty();

  currentSelection.append("<p>Filtering on:");

  var scope = this;

  $.each(this.selectedSearch, function (searchMenuCatagory, selection) {
    var e = $('<a href="#">[X] ' + searchMenuCatagory + ":" + selection + '</a>');
    e.onclick(function(){
      var searchFilter = $(this).text();

      var search = "";
      for (var j = 0; j < searchFilter.length; ++j) {
        search += searchFilter[j] + " ";
      }
      console.log("Split values: '" + search + "'");

      delete this.selectedSearch[searchFilter[0]];
      this.query(catalog, selectedSearch, onData, 1);
      populateCurrentSelections();
    });
    currentSelection.append(e);
  });

  currentSelection.append("</p>");
  */
}
