var lmore = function(options) {
  //Default options
  this.def_option = {
    elem: NaN,
    source: NaN,
    count: 3
  };

  //set the properties
  if (options) {
    for (key in options) {
      if (this.def_option.hasOwnProperty(key)) {
        this[key] = options[key];
      }
    }
  }

  //Http request variable
  this.http = 0;

  //Starting point
  this.start = 1;

  //Load more button
  this.load_more = false;

  //Whether it load more button was clicked or not
  this.is_load_more = false;

  //set load more button
  if (this.elem.getElementsByClassName('load_more')[0]) {
    this.load_more = this.elem.getElementsByClassName('load_more')[0];
    this.load_more_display = this.load_more.style.display;
    this.load_more.style.display = 'none';
  }

  //Clone .item and remove it from DOM
  this.items = this.elem.getElementsByClassName('items')[0];
  this.itemo = this.items.getElementsByClassName('item')[0];
  this.item = this.itemo.cloneNode(true);
  this.items.removeChild(this.itemo);
  this.nores = this.elem.getElementsByClassName('nores')[0];
  this.rescont = this.elem.getElementsByClassName('rescont')[0];
  this.resdis = this.rescont.style.display;

  //function to remove .item from DOM
  this.remove = function() {
    while (this.items.firstChild) {
      this.items.removeChild(this.items.firstChild);
    }
  }

  //Function to set value of any element
  //params el - element to set value to
  //val - the value to be set
  this.set_val = function(el, val) {
    var node_type = el.nodeName.toLowerCase();
    if (node_type != 'input' && node_type != 'select' && node_type != 'textarea') {
      el.innerHTML = val;
      return true;
    }
    if (node_type == 'select' || (node_type == 'input' && el.type != 'checkbox') || node_type == 'textarea') {
      if (el.hasAttribute('multiple')) {
        this.multi_set(el, val);
        return true;
      }
      el.value = val;
      return true;
    } else if (el.type == 'checkbox') {
      el.checked = (val == '1') ? true : false;
      return true;
    }
    return false;
  }

  //Function to set value of select multiple
  this.multi_set = function(sel, values) {
    var vals = Array.isArray(values) ? values : String(values).split(',');
    var opt;
    for (var i = 0, len = sel.options.length; i < len; i++) {
      opt = sel.options[i];
      opt.selected = false;
      for (var x = 0, q = vals.length; x < q; x++) {
        if (opt.value == vals[x]) {
          opt.selected = true;
        }
      }
    }
  }

  //Append API data to DOM
  this.append = function(value) {

    //Create a clone of the .item
    var clone = this.item.cloneNode(true);

    //select all elements in .item
    //with data-field attribute
    var subs = clone.querySelectorAll('[data-field]');

    //loop through API result
    for (name in value) {
      if (value.hasOwnProperty(name)) {

        //loop through elements
        //with data-field attr
        for (var i = 0, q = subs.length; i < q; i++) {

          //id attr = key of object
          //set value
          if (subs[i].getAttribute('data-field') == name) {
            var ptext = value[name];
            var text = document.createTextNode(ptext);
            this.set_val(subs[i], ptext);
          }
        }
      }
    }

    //append the cloned element
    //to .items
    this.items.appendChild(clone);
  };

  //Load data from API
  this.load = function() {
    //Check if load more button was clicked
    if (!this.is_load_more) {
      this.start = 1;
      this.remove();
    } else {
      this.start += this.count;
    }


    this.is_load_more = false;

    //Abort pending ajax calls if any
    if (this.http != 0) {
      this.http.abort();
    }

    //Ajax request
    this.http = new XMLHttpRequest();
    this.http.onreadystatechange = function() {
      if (this.http.readyState == 4 && this.http.status == 200) {
        res = JSON.parse(this.http.responseText);
        resp = res.items;

        //If last result hide load more button else show
        if (this.load_more) {
          if (!res.last) {
            this.load_more.style.display = this.load_more_display;
          } else {
            this.load_more.style.display = 'none';
          }
        }

        //Check if there are results
        //If not the no results text is shown
        if (undefined !== resp && resp != null && resp.length) {
          //Loop through each result set
          //and pass it to append function
          for (var i = 0, q = resp.length; i < q; i++) {
            this.append(resp[i]);
          }
          this.nores.style.display = 'none';
          this.rescont.style.display = this.resdis;
        } else {
          this.nores.style.display = 'block';
          this.rescont.style.display = 'none';
        }
      }
    }.bind(this);
    //.bind is used so that 'this' is set
    //to lmore object

    //create query string with
    //start and count variables
    var qs = this.source + '?lmore_start=' + this.start + '&lmore_count=' + this.count;
    this.http.open('GET', qs);
    this.http.send();
  };

  //Load first set of data on page load
  this.load('');

  //The load more button on click would load
  //the nextr set of results
  if (this.load_more) {
    this.load_more.addEventListener('click', function() {

      //is_load_more is set to true
      //so that start is not reset
      this.is_load_more = true;
      this.load();
    }.bind(this));
  }
}
