var bind = function(obj, method) {
  var args = Array.prototype.slice.call(arguments);
  args.shift();
  args.shift();
  return function() {
    var args2 = Array.prototype.slice.call(arguments);
    method.apply(obj, args.concat(args2));
  }
};

var combine = function(f1, f2) {
  return function() {
    if (f1) {
      f1.apply(this, arguments);
    }
    if (f2) {
      f2.apply(this, arguments);
    }
  };
};

var registerOnload = function(f) {
  window.onload = combine(window.onload, f);
};


dom = {};

dom.addClass = function(element, className) {
  element.setAttribute('class', element.className + ' ' + className);
};

dom.removeClass = function(element, className) {
  var re = new RegExp('\\b' + className + '\\b', 'g');
  element.setAttribute('class', element.className.replace(re, ''));
};


Cookies = function() {
}

Cookies.prototype.get = function(key) {
  if (!this.map) {
    this.parseCookies();
  }
  return this.map[key];
};

Cookies.prototype.set = function(key, value, days) {
  var cookie = key + '=' + value;
  if (!days) {
    document.cookie = cookie;
    return;
  }

  var expires = new Date();
  expires.setDate(expires.getDate() + days);
  cookie = cookie + ';expires=' + expires.toGMTString();
  console.log('cookie =', cookie);
  document.cookie = cookie;
}

Cookies.prototype.parseCookies = function() {
  this.map = {};
  var cookies = document.cookie.split(';');
  for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i];
    var eq = cookie.indexOf('=');
    this.map[cookie.substr(0, eq).replace(' ', '')] = cookie.substr(eq + 1);
  }
}


Ajax = function() {
  this.params = [];
}

Ajax.prototype.addParam = function(key, value) {
  if (value !== undefined) {
    this.params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
  } else {
    this.params.push(encodeURIComponent(key));
  }
}

Ajax.prototype.addField = function(field) {
  this.addParam(field, document.getElementById(field).value);
}

Ajax.prototype.send = function(url, onSuccess, onFailure) {
  var http;
  if (window.XMLHttpRequest) {
    // Mozilla/Safari
    http = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    // IE
    http = new ActiveXObject("Microsoft.XMLHTTP");
  } else {
    onFailure && onFailure();
  }
  http.open('POST', url, true);

  var paramString = this.params.join('&');
  http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  //http.setRequestHeader("Content-length", paramString.length);
  //http.setRequestHeader("Connection", "close");

  http.onreadystatechange = function() {
    if(http.readyState == 4) {
      if (http.status == 200) {
        onSuccess && onSuccess(http.responseText);
      } else {
        onFailure && onFailure();
      }
    }
  }
  http.send(paramString); 
}

function sendFeedback() {
  if (!confirm('Do you want to send this feedback to David?')) {
    return false;
  }
  var feedback = document.getElementById('feedbackq').value;
  if (!feedback) return;

  var sendButton = document.getElementById('sendButton');
  sendButton.value = 'sending...';

  var url = "feedback.php";
  var ajax = new Ajax();
  ajax.addParam('feedback', feedback);
  ajax.addParam('url', window.location);

  var inputs = document.getElementsByTagName('input');
  for (var i = 0; i < inputs.length; i++) {
    var element = inputs[i];
    var name = element.name;
    var value = element.type == 'checkbox' ? element.checked : element.value;
    if (name && value) {
      ajax.addParam(name, value);
    }
  }

  ajax.addParam('document', document.documentElement.innerHTML);
  ajax.send(url, function(response) {
        sendButton.value = 'send';
        alert(response);
      },
      function() { alert('Failed to send feedback.'); }
  );
}

function onKeyUp(input, f, e) {
  var event = e || window.event;
  if (event.keyCode == 13) {
    f();
    input.blur();
  }
}



function InputMenu(inputElement, menuElement, getMenuItems) {
  this.inputElement = inputElement;
  this.menuElement = menuElement;
  this.getMenuItemsFunc = getMenuItems;
  this.itemCount = 0;
  this.selectedItem = -1;
  this.hide();

  inputElement.setAttribute("autocomplete", "off");
  inputElement.onkeydown = bind(this, this.onKeyDown);
  inputElement.onkeyup = bind(this, this.onKeyUp);
  inputElement.onblur = combine(
      inputElement.onblur, bind(this, this.hide));
  inputElement.onfocus = combine(
      inputElement.onfocus, bind(this, this.getMenuItems));
  var menu = this;
  menuElement.onmousedown = function(e) {
    var event = e || window.event;
    event.preventDefault();
    menu.hide();
  }
}

InputMenu.prototype.show = function() {
  this.menuElement.style.display = '';
}

InputMenu.prototype.hide = function() {
  this.menuElement.style.display = 'none';
}

InputMenu.prototype.setMenuItems = function(items) {
  if (!items) {
    this.itemCount = 0;
    this.hide();
    return;
  }
  this.menuElement.innerHTML = '';
  var itemArray = items.split('\n');
  this.itemCount = 0;
  for (var i = 0; i < itemArray.length; i++) {
    if (!itemArray[i]) {
      continue;
    }
    this.itemCount++;
    var itemElement = document.createElement('div');
    itemElement.className = 'menuItem';
    itemElement.innerHTML = itemArray[i];
    var inputElement = this.inputElement;
    itemElement.onmouseover = function(index, menu) {
      return function() {
        menu.selectItem(index);
      };
    }(i, this);

    this.menuElement.appendChild(itemElement);
  }
  this.selectedItem = -1;
  if (this.itemCount > 0) {
    this.show();
  } else {
    this.hide();
  }
}

InputMenu.prototype.selectNextItem = function(delta) {
  this.selectItem(this.selectedItem + delta);
}

InputMenu.prototype.selectItem = function(index) {
  if (this.selectedItem == -1) {
    this.originalInput = this.inputElement.value;
  } else {
    var oldItem = this.menuElement.childNodes[this.selectedItem];
    oldItem.className = 'menuItem';
  }

  this.selectedItem = index;
  if (this.selectedItem < -1) {
    this.selectedItem = this.itemCount - 1;
  }
  if (this.selectedItem >= this.itemCount) {
    this.selectedItem = -1;
  }

  if (this.selectedItem == -1) {
    this.inputElement.value = this.originalInput;
  } else {
    var newItem = this.menuElement.childNodes[this.selectedItem];
    newItem.className = 'selected menuItem';
    this.inputElement.value = newItem.innerHTML;
  }
};

InputMenu.prototype.onKeyDown = function(e) {
  var event = e || window.event;
  if (event.keyCode == 27) {
    this.selectItem(-1);
    this.hide();
  } else if (event.keyCode == 38) {
    this.selectNextItem(-1);
    event.preventDefault();
  } else if (event.keyCode == 40) {
    this.selectNextItem(1);
    event.preventDefault();
  }
};

InputMenu.prototype.onKeyUp = function(e) {
  var event = e || window.event;
  if (event.keyCode <= 40 && event.keyCode != 8 && event.keyCode != 32) {
    return;
  }
  this.getMenuItems();
};

InputMenu.prototype.getMenuItems = function() {
  this.getMenuItemsFunc(this.inputElement.value, bind(this, this.setMenuItems));
};


function registerInputMenu(inputId, menuId, getMenuItems) {
  var inputElement = document.getElementById(inputId);
  var menuElement = document.getElementById(menuId);
  var menu = new InputMenu(inputElement, menuElement, getMenuItems);
}

function getSuggestions(field, value, setMenuItems) {
  /*
  if (value.length < 1) {
    setMenuItems(false);
    return;
  }
*/
  var ajax = new Ajax();
  ajax.addParam('suggest', field);
  ajax.addParam(field, value);
  ajax.send('search.php', setMenuItems);
}

function showMoreCards(query, order1, order2) {
  document.getElementById('showMoreCards').innerHTML = 'Fetching more cards...';

  var ajax = new Ajax();
  ajax.addParam('submit_action', 'show more cards');
  ajax.addParam('use_condition', true);
  ajax.addParam('and_condition', query);
  if (order1) {
    ajax.addParam('order1', order1);
  }
  if (order2) {
    ajax.addParam('order2', order2);
  }

  var inputs = document.getElementsByTagName('input');
  for (var i = 0; i < inputs.length; i++) {
    var name = inputs[i].name;
    if (name.substr(0, 8) == 'display_' && name != 'display_image') {
      ajax.addParam(name, inputs[i].checked);
    }
  }

  var moreCardsDiv = document.getElementById('moreCards');
  ajax.send('search.php', function(result) {
    //alert('test');
    moreCardsDiv.innerHTML = result;
  }, function() {
    moreCardsDiv.innerHTML = 'Failed to fetch more cards.';
  });
}

function getElementsByClass(className, tag) {
  if (document.getElementsByClassName) {
    return document.getElementsByClassName(className);
  }
  var tags = document.getElementsByTagName(tag);
  var result = [];
  for (var i = 0; i < tags.length; i++) {
    if (tags[i].className.indexOf(className) != -1) {
      result.push(tags[i]);
    }
  }
  return result;
};

registerOnload(function() {
  var elements = getElementsByClass('described', 'input');
  var onFocus = function() {
    if (this.className.indexOf('described') != -1) {
      dom.removeClass(this, 'described');
      //this.className = '';
      this.value = '';
    }
  };
  var onBlur = function(description) {
    if (this.value == description || this.value == '') {
      dom.addClass(this, 'described');
      //this.className = 'described';
      this.value = description;
    }
  };
  var undescribeAll = function() {
    var elements = getElementsByClass('described', 'input');
    for (var i = 0; i < elements.length; i++) {
      elements[i].value = '';
    }
  }
  for (var i = 0; i < elements.length; i++) {
    elements[i].onfocus = onFocus;
    elements[i].onblur = bind(elements[i], onBlur, elements[i].value);
    elements[i].form.onsubmit = undescribeAll;
  }
});

