//{@ @todo: this need to be configured before the document load
var catalog = "/catalog/myUniqueName";
var config = {
  host: "atmos-csu.research-lan.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);
            });
          });

          //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,
  };

  /*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").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(){
          scope.onQueryData.apply(scope, arguments);
        },
        function(){
          scope.onQueryTimeout.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 = 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){
  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(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().map(function(obj, index){
      return $(obj).text();
  }, []);
  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>");
  */
}
