var ajax_Timer, ajax_backup_message;

function handle_enter_redirect(evt, url) {
var kcode;
if (!evt) var evt = window.event;
if (evt.keyCode) {
  kcode = evt.keyCode;
}
else {
  if (evt.which) kcode = evt.which;
}

stopEvent(evt);

if (kcode == 13 || kcode == 3) {
  window.location = url;
  return false;
}
return true;
}



/**
 * function addEvent associates an event with an object
 * example1 : addEvent(document.getElementById('contact_search'), 'keyup', function (ev) { handle_enter_redirect(ev, 'contacts.php'); }, true);
 * example2 : addEvent(window, "load", create_ajax_suggest('contacts', 'contact_name', 'contact_search', 'div_contact_search', 25, 'contacts.php?btn_search=1&filter_contact_name='), false);
 * open blog : http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html
 */
function addEvent(obj, evType, fn, useCapture) {
  if (typeof fn != "function") { alert(fn + ' is not a function!'); return false; }

  useCapture = useCapture || false;
  if (evType == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || obj.attachEvent)) evType = 'keyup';
  if (obj.addEventListener)
  {
    obj.addEventListener(evType, fn, useCapture);
    return true;
  }
  else if (obj.attachEvent)
  {
    if (useCapture)
    {
			alert('IE does not support event capturing!');
			return false;
    }
    else
    {
      var r = obj.attachEvent("on" + evType, fn);
    }
    return r;
  }
  else
  {
		alert('Handler could not be attached');
		return false;
  }
}



/**
 * The nice thing about this one is that if any other events were previously assigned to window.onload
 * this script will not override it, but will add the stated functions to it.
 */
function addLoadEvent(fn) {
  if (typeof fn == "function") {
    var oldonload = window.onload;
    if (typeof window.onload != "function") {
      window.onload = fn;
    } else {
      window.onload = function() {
        oldonload();
        fn();
      }
    }
	}
}



function removeEvent(obj, evType, fn, useCapture)
{
  useCapture = useCapture || false;
  if (evType == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || obj.detachEvent)) evType = 'keyup';
  if (obj.removeEventListener)
  {
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  }
  else if (obj.detachEvent)
  {
    var r = obj.detachEvent("on" + evType, fn);
    return r;
  }
  else
  {
		alert('Handler could not be removed');
		return false;
	}
}



function stopEvent(ev) {
  if (!ev) var ev = window.event;
  if (ev.preventDefault)
  {
    ev.preventDefault();
    ev.stopPropagation();
  }
  else
  {
    ev.cancelBubble = true;
    ev.returnValue = false;
  }
};

function display_custom_message(new_message) {
  var id_timeout,element_name = 'custom_message';
  if (document.getElementById(element_name)) {
    var dv = document.getElementById(element_name);
    if (!ajax_backup_message) ajax_backup_message = dv.innerHTML;
    dv.innerHTML = new_message;
    check_custom_message(ajax_backup_message);
  }
  else {
    window.status = new_message;
  }
}

function check_custom_message(old_message) {
	if (ajax_Timer) clearTimeout(ajax_Timer);
	ajax_Timer = setTimeout("restore_custom_message('" + old_message + "')", 2000);
}

function restore_custom_message(old_message) {
  var element_name = 'custom_message';
  if (document.getElementById(element_name)) {
    var dv = document.getElementById(element_name);
    dv.innerHTML = old_message;
  }
}

function handle_ajax_request(request) {
  temp = request.responseText.split('&');
  // strip anything but numbers
  temp[0] = temp[0].replace(/[^0-9]/g, '');

  if (typeof temp[1] == "undefined") {
    display_custom_message('<span style="color:#cc0000">Error: ' + request.responseText + '</span>');
    return false;
  }
  else {
    temp[1] = temp[1].replace(/\'/g, '');
    if (!temp[0] || temp[1] != 'Success') {
      if (temp[2]) {
        temp[2] = temp[2].replace(/\'/g, '');
        var err_string = unescape(temp[2]);
      }
      else {
        var err_string = 'Failed';
      }
      display_custom_message('<span style="color:#cc0000">Error: ' + err_string + '</span>');
      return false;
    }
    else {
      var striped_temp = new Array();
      for (var i = 2; i< temp.length; i++) {
        striped_temp[i-2] = unescape(temp[i]);
      }
      return striped_temp;
    }
  }
}

function updateDropdown(elId, elArray)
{
  var el = document.getElementById(elId);
  clearDropdown(elId);

  for (var i=0; i<elArray.length; i+=2)
    el.options[(i/2)] = new Option(elArray[(i+1)], elArray[i], false, false);
}

function clearDropdown(elId)
{
  var el = document.getElementById(elId);
  for (var j=(el.options.length-1); j>=0; j--)
    el.options[j] = null;
  el.options.length = 0;
}

function getElemAttr(r,attr){
  var kb=0;
  while(r){
    kb+=r[attr];
    r=r.offsetParent
  }
  return kb
}

function calculateWidth(r){
  var borderright=1;
  if(navigator&&navigator.userAgent.toLowerCase().indexOf("msie")==-1){
    return r.offsetWidth-borderright*2
  }else{
    return r.offsetWidth
  }
}

/**
 * Used to populate a select box after an ajax event
 *
 * @param  ajax request string
 * @param  select box target id
 * @param  (optional) default dropdown value
 * @return void
 */
function ajax_populate_dropdown() {
  var i,tid,req='',def='Please choose...',args=ajax_populate_dropdown.arguments;
  for (i=0; i<args.length; i++) {if (i==0) req=args[i]; if (i==1) tid=args[i]; if (i==2) def=args[i];}
  var temp = handle_ajax_request(req);
  if (temp[0].length) var strout = ", " + temp[0]; else var strout = " ";
  var z = eval("new Array('0', '" + def + "'" + strout + ")");
  updateDropdown(tid, z);
}

function ajax_many_to_many(join_table_name, join_primary_key, link_table_name, link_primary_key, link_field_name, child_primary_key, child_live_key, start, anchor_id, form_mode, record_url, popup_title, additional_parameters)
{
  var url        = 'ajax_many_to_many.php';
  var parameters = 'join_table_name=' + join_table_name + '&join_primary_key=' + join_primary_key + '&link_table_name=' + link_table_name + '&link_primary_key=' + link_primary_key + '&link_field_name=' + escape(link_field_name) + '&child_primary_key=' + child_primary_key + '&child_live_key=' + child_live_key + '&start=' + start + '&anchor_id=' + anchor_id + '&form_mode=' + form_mode + '&record_url=' + escape(record_url) + '&popup_title=' + popup_title;
  if (additional_parameters) parameters = parameters + additional_parameters;
  var myAjax     = new Ajax.Request(url,{method: 'get', parameters: parameters, onComplete: function(request) {myFloat.write('AjaxPopup', request.responseText, popup_title); myFloat.show(anchor_id, 'AjaxPopup');}});
}
function ajax_custom_add(table_name, primary_key, field_1, value_1, field_2, value_2)
{
  var url        = 'ajax_inserter.php';
  var parameters = 'table_name=' + table_name + '&primary_key=' + primary_key + '&fields[' + field_1 + ']=' + value_1 + '&fields[' + field_2 + ']=' + value_2;
  var myAjax     = new Ajax.Request(url,{method: 'get', parameters: parameters, onComplete: function(request) {var handled_string = handle_ajax_request(request);if (handled_string) display_custom_message('Record added');}});
}

function ajax_custom_update() {
  var i,args=ajax_custom_update.arguments,url="ajax_updater.php";
  var table_name=args[0],primary_key=args[1],live_key=args[2];
  var parameters='table_name=' + table_name + '&where[' + primary_key + ']=' + live_key;
  for (i=3;i<args.length;i+=2) { parameters += '&fields[' + args[i] + ']=' + args[i+1]; }
  var myAjax = new Ajax.Request(url,{method:"get",parameters:parameters,onComplete:function(request){var handled_string = handle_ajax_request(request);if (handled_string) display_custom_message("Record updated");}});
}

function ajax_custom_remove(table_name, primary_key, field_1, value_1, field_2, value_2)
{
  var url        = 'ajax_remover.php';
  var parameters = 'table_name=' + table_name + '&primary_key=' + primary_key + '&filters[' + field_1 + ']=' + value_1 + '&filters[' + field_2 + ']=' + value_2;
  var myAjax     = new Ajax.Request(url,{method: 'get', parameters: parameters, onComplete: function(request) {var handled_string = handle_ajax_request(request);if (handled_string) {display_custom_message('Record removed');}}});
}

/**
 *
 * ajax suggest main class
 *
 */
function ajax_suggest(tableName, fieldName, oText, mainDiv, nMaxSize, redirect_on_click, additional_params) {
  // initialize member variables
  this.oText         = oText;
  this.mainDiv       = mainDiv;
  this.redirect_url  = redirect_on_click;
  this.nMaxSize      = nMaxSize;
  this.aStr          = new Array(0);       // used to store all the records
  this.tableName     = tableName;
  this.fieldName     = fieldName;
  this.selectedIndex = 0;                 // used at selecting the current record
  this.additional_params = additional_params;

  // attach handlers to the text-box
  oText.ajax_suggest = this;

  oText.onkeyup = ajax_suggest.prototype.onTextChange;
  oText.onblur = ajax_suggest.prototype.onTextBlur;
}


ajax_suggest.prototype.onTextBlur = function() {
  this.ajax_suggest.hide();
}

ajax_suggest.prototype.hide = function() {
  this.mainDiv.innerHTML = "";
  this.mainDiv.style.visibility = "hidden";
}

ajax_suggest.prototype.show = function() {
  this.mainDiv.style.visibility = "visible";
  this.mainDiv.style.top        = this.oText.offsetHeight-1 + "px"; // || getElemAttr(this.oText, "offsetTop") + this.oText.offsetHeight-1 + "px";
  this.mainDiv.style.width      = calculateWidth(this.oText) + "px";
}

ajax_suggest.prototype.onTextChange = function(ev) {
  var kcode;
  if (!ev) var ev = window.event;
  if (ev.keyCode) {
    kcode = ev.keyCode;
  }
  else {
    if (ev.which) kcode = ev.which;
  }

  // c4xp: Safari has some issues with document.onkeydown and its brothers document.onkeypress and document.onkeyup.
  // As far as I can tell, it will always fire the event twice unless their handlers return false.
  // This is inconvenient, because if you set the handler to always return false, the user will never be able to type anything.
  // That's why I've done this conditional returning stuff, so problems should be avoided.
	switch (kcode) {
		// up arrow key
		case 38:
    if (this.ajax_suggest.selectedIndex > 1)
    {
      // restore old selectedIndex
      if (document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex))
      {
        this.ajax_suggest.fadelight( document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex) );
      }
      // decrease the selectedIndex accordingly
      this.ajax_suggest.selectedIndex = ( this.ajax_suggest.selectedIndex * 1 ) - 1;
      // select the new Index
      if (document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex))
      {
        this.ajax_suggest.highlight( document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex) );
      }
      this.ajax_suggest.oText.value = this.ajax_suggest.aStr[this.ajax_suggest.selectedIndex - 1];
    }
    return false;
      break;
		// down arrow key
		case 40: 
      if (this.ajax_suggest.selectedIndex < this.ajax_suggest.aStr.length)
      {
        // restore old selectedIndex
        if (document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex))
        {
          this.ajax_suggest.fadelight( document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex) );
        }
        // increase the selectedIndex accordingly
        this.ajax_suggest.selectedIndex = ( this.ajax_suggest.selectedIndex * 1 ) + 1;
        // select the new Index
        if (document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex))
        {
          this.ajax_suggest.highlight( document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex) );
        }
        this.ajax_suggest.oText.value = this.ajax_suggest.aStr[this.ajax_suggest.selectedIndex - 1];
      }
      return false;
      break;
    // enter key
    case  3:
    case 13: window.location = this.ajax_suggest.redirect_url + this.ajax_suggest.oText.value; return false; break;
    default: this.ajax_suggest.retrieve(); return false;
	}
}

ajax_suggest.prototype.onDivMouseDown = function(ev) {
  if (!this.ajax_suggest.redirect_url) {
    this.ajax_suggest.oText.value = this.innerHTML;
  }
  else {
    window.location = this.ajax_suggest.redirect_url + this.innerHTML;
  }
  return stopEvent(ev);
}

ajax_suggest.prototype.onDivMouseOver = function(ev) {
  // this is for when the mouse is hovering and the user is pressing up/down key
  if (document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex))
  {
    this.ajax_suggest.fadelight( document.getElementById('oDiv_' + this.ajax_suggest.selectedIndex) );
  }
  this.ajax_suggest.highlight(this);
  // select the new selectedIndex by mouse hover
  temp = this.id.split('Div_', 2);
  // strip anything but numbers
  temp[1] = temp[1].replace(/[^0-9]/g, '');
  this.ajax_suggest.selectedIndex = temp[1];
  return stopEvent(ev);
}

ajax_suggest.prototype.onDivMouseOut = function(ev) {
  this.ajax_suggest.fadelight(this);
  return stopEvent(ev);
}

ajax_suggest.prototype.fadelight = function(el) {
  el.style.backgroundColor = "#ffffff";
  el.style.color = "#000000";
}

ajax_suggest.prototype.highlight = function(el) {
  el.style.backgroundColor = "#000033";
  el.style.color = "#ffffff";
}

//Using Closures To Support Object-Oriented AJAX
ajax_suggest.prototype.retrieve = function() {
  var _this = this; // ver.0 (works ok) don't overload the meaning of 'this'
  //var update = function(req) { ajax_suggest.populate(req); } // ver.1 (doesnt work ?!)
  //update.ajax_suggest = this; // ver.2 (doesnt work ?!)
  var txt = escape(this.oText.value);
  if (txt.length >= 3)
  {
    var url        = 'ajax_loopback.php';
    var parameters = 'table_name=' + this.tableName + '&fields[0]=' + this.fieldName + '&like_filters[' + this.fieldName + ']=' + txt + this.additional_params;
    var tempArr    = new Array(0);

    var myAjax = new Ajax.Request(
    url,
    {
    method: 'get',
    parameters: parameters,
    onComplete: function(req) { _this.populate(req); }
    });
    //onComplete: function(req) { _this.populate(req); } // ver.0 (works ok)
    //onComplete: update // ver.1 (doesnt work ?!)
    //onComplete: this.update.bind(this) // ver.2 (doesnt work ?!)
  }
  else
  {
    this.hide();
  }
}

ajax_suggest.prototype.populate = function(request) {
  var handled_string = handle_ajax_request(request);
  this.aStr = eval("[" + handled_string + "]");

  // count the number of strings that match the text-box value
  var nCount = this.aStr.length;

  // if a suitable number then show the popup-div
  if ( (this.nMaxSize == -1 ) || ((nCount < this.nMaxSize) && (nCount > 0)) )
  {
    // clear the popup-div.
    while ( this.mainDiv.hasChildNodes() )
      this.mainDiv.removeChild(this.mainDiv.firstChild);


    // add each string to the popup-div
    var i, n = this.aStr.length;
    var divIndex = 0;
    for ( i = 0; i < n; i++ )
    {
      var oDiv = document.createElement('div');
      this.mainDiv.appendChild(oDiv);
      oDiv.innerHTML   = this.aStr[i];
      divIndex         = ( i * 1 ) + 1;
      oDiv.id          = 'oDiv_' + divIndex;
      oDiv.onmousedown = ajax_suggest.prototype.onDivMouseDown;
      oDiv.onmouseover = ajax_suggest.prototype.onDivMouseOver;
      oDiv.onmouseout  = ajax_suggest.prototype.onDivMouseOut;
      oDiv.ajax_suggest = this;
    }
    this.show();
  }
  else
  {
    this.hide();
  }
}

function create_ajax_suggest(tableName, fieldName, input_name, div_name, nmax, redirect_url, additional_params)
{
  return new ajax_suggest(
    tableName,
    fieldName,
    document.getElementById(input_name),
    document.getElementById(div_name),
    nmax,
    redirect_url,
    additional_params
    );
}
