/////////////////////////////////////
// jqpie_complete code
// Original Code came from http://www.dyve.net/jquery/?autocomplete
/////////////////////////////////////



$.jqpie_complete = function(input, options) {
  // Create a link to self
  var me = this;
  // Create jQuery object for input element
  var $input = $(input).attr("autocomplete", "off");;

  // Hold the current query
  var cquery = '';

  // Create results
  var results = document.createElement("div");
  // Create jQuery object for results
  var $results = $(results);
  $results.css('min-width', $input.width());
  // Set default values for results
  var pos = findPos(input);
  $results[options.hideeffect](options.hidespeed).addClass(options.resultsClass).css({
    position: "absolute",
    top: (pos.y + (input.offsetHeight)) + "px",
    left: pos.x + "px"
  });
  // Add to body element
  $("body").append(results);

  input.autocompleter = me;
  input.lastSelected = $input.val();

  var timeout = null;
  var prev = "";
  var active = -1;
  var cache = {};
  var keyb = false;
  $input
  .keydown(function(e) {
    switch(e.keyCode) {
      case 38: // up
        e.preventDefault();
        moveSelect(-1);
        break;
      case 40: // down
        e.preventDefault();
        moveSelect(1);
        break;
      case 9:  // tab
      case 13: // return
        if (selectCurrent()) {
          e.preventDefault();
        }
        break;
      default:
        active = -1;
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(onChange, options.delay);
        break;
    }
  })
  .blur(function() {
    hideResults();
  });

  hideResultsNow();

  function onChange() {
    var v = $input.val();
    if(options.waitElementID){
        $('#'+options.waitElementID)[options.showeffect](options.showspeed);
    }
    if (v.length >= options.minChars) {
      $input.addClass(options.loadingClass);
      requestData(v);
    } else {
      $input.removeClass(options.loadingClass);
      $results[options.hideeffect](options.hidespeed);
    }
  };

  function moveSelect(step) {

    var lis = $("li", results);
    if (!lis) return;

    active += step;

    if (active < 0) {
      active = 0;
    } else if (active >= lis.size()) {
      active = lis.size() - 1;
    }

    lis.removeClass("over");

    $(lis[active]).addClass("over");

    // Weird behaviour in IE
    // if (lis[active] && lis[active].scrollIntoView) {
    //  lis[active].scrollIntoView(false);
    // }

  };

  function selectCurrent() {
    var li = $("li.over", results)[0];
    if (!li) {
      var $li = $("li", results);
      if (options.selectOnly) {
        if ($li.length == 1) li = $li[0];
      } else if (options.selectFirst) {
        li = $li[0];
      }
    }
    if (li) {
      selectItem(li);
      return true;
    } else {
      return false;
    }
  };

  function selectItem(li) {
    if (!li) {
      li = document.createElement("li");
      li.extra = [];
      li.selectValue = "";
    }
    var v = $.trim(li.selectValue ? li.selectValue : li.innerHTML);
    input.lastSelected = v;
    prev = v;
    $results.html("");
    $input.val(v);
    hideResultsNow();
    if (options.onItemSelect) {
      if(options.jqpie) {
        $input.jqpie(options.url, { callback: options.onItemSelect, params: li.extra[options.onItemSelect_key] });
      } else {
        setTimeout(function() { options.onItemSelect(li, data) }, 1);
      }
    }
  };

  function hideResults() {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(hideResultsNow, 200);
  };

  function hideResultsNow() {
    if (timeout) clearTimeout(timeout);
    $input.removeClass(options.loadingClass);
    if ($results.is(":visible")) {
      $results[options.hideeffect](options.hidespeed);
    }
    if (options.mustMatch) {
      var v = $input.val();
      if (v != input.lastSelected) {
        selectItem(null);
      }
    }
  };

  function receiveData(q, data) {
    if (data) {
      $input.removeClass(options.loadingClass);
      results.innerHTML = "";
      if ($.browser.msie) {
        // we put a styled iframe behind the calendar so HTML SELECT elements don't show through
        $results.append(document.createElement('iframe'));
      }
      results.appendChild(dataToDom(data));
      $results[options.showeffect](options.showspeed);
    } else {
      hideResultsNow();
    }
  };

  function dataToDom(data) {
      var pos = findPos(input);
      $results.hide().css({
        position: "absolute",
        top: (pos.y + (input.offsetHeight)) + "px",
        left: pos.x + "px"
      });

    var ul = document.createElement("ul");
    if(data == -1) {
        var li = document.createElement("li");
        li.innerHTML = 'No Match Found';
        ul.appendChild(li);
        return ul;
    }
    var num = data.length;
    for (var i=0; i < num; i++) {
      var li = document.createElement("li");
      if(data[i].show && data[i].value) {
        li.innerHTML = data[i].show;
        li.selectValue = data[i].value;
        li.extra = data[i];
      } else {
        li.innerHTML = data[i].show;
        li.extra = data[i];
      }
      li.datarow = i;
      li.inputid = input.id;
      ul.appendChild(li);
      $(li).hover(
        function() { $("li", ul).removeClass("over"); $(this).addClass("over"); },
        function() { $(this).removeClass("over"); }
      ).click(function(e) { e.preventDefault(); e.stopPropagation(); selectItem(this) });
    }
    return ul;
  };

  function requestData(q) {
    if (!options.matchCase) {
        q = q.toLowerCase();
    }
    var rdata = null;
    if (options.use_cache) {
        rdata = options.cacheLength ? loadFromCache(q) : null;
    }
    if (rdata) {
      receiveData(q, rdata);
    } else {
      // onResponse is called when request has completed!!!
      cquery = q;
      $.getJSON(options.url, { handler: 'json', callback: options.callback }, function(json) {
      data = json;
      ischanged();
      });
    }
  };

  function ischanged() {
    if (options.use_cache && data) {
      addToCache(cquery, data);
    }
    receiveData(cquery, data);
    if(options.waitElementID){
        $('#'+options.waitElementID)[options.hideeffect](options.hidespeed);
    }
  }


  function loadFromCache(q) {
    if (!q) return null;
    if (cache[q]) return cache[q];
    return null;
  };


  this.flushCache = function() {
    cache = {};
  };

  function addToCache(q, data) {
    if (!data || !q || !options.cacheLength) return;
    if (!cache.length || cache.length > options.cacheLength) {
      cache = {};
      cache.length = 1; // we know we're adding something
    } else if (!cache[q]) {
      cache.length++;
    }
    cache[q] = data;
  };

  function findPos(obj) {
    var curleft = obj.offsetLeft || 0;
    var curtop = obj.offsetTop || 0;
    while (obj = obj.offsetParent) {
      curleft += obj.offsetLeft
      curtop += obj.offsetTop
    }
    return {x:curleft,y:curtop};
  }
}

$.fn.jqpie_complete = function(url, options) {
  var data = new Array();
  // Make sure options exists
  options = options || {};
  options.url = url;
  // Set default values for required options
  options.resultsClass = options.resultsClass || "ac_results";
  options.minChars = options.minChars || 1;
  options.delay = options.delay || 200;
  options.matchCase = options.matchCase || 0;
  options.cacheLength = options.cacheLength || 1;
  options.mustMatch = options.mustMatch || 0;
  options.loadingClass = options.loadingClass || "ac_loading";
  options.selectFirst = options.selectFirst || false;
  options.selectOnly = options.selectOnly || false;
  options.use_cache = options.use_cache || 1;
  options.hidespeed = options.hidespeed || 0;
  options.showspeed = options.showspeed || 0;
  options.hideeffect = options.hideeffect || 'hide';
  options.showeffect = options.showeffect || 'show';
  options.onItemSelect_key = options.onItemSelect_key || 'value';
  options.callback = options.callback || 'autocomp';
  // If a jqpie is provided the onSelect callback uses jqpie
  options.jqpie = options.jqpie ||  0;
  this.each(function() {
    var input = this;
    new $.jqpie_complete(input, options);
  });

  // Don't break the chain
  return this;
}
    

/*
// +-----------------------------------------------------------------------------+
// | Copyright (c) 2005 Cyberlot Technologies Group                              |
// +-----------------------------------------------------------------------------+
// | GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt    |
// | Permits anyone the right to use and modify the software without limitations |
// | as long as proper  credits are given  and the original  and modified source |
// | code are included. Requires  that the final product, software derivate from |
// | the original  source or any  software  utilizing a GPL  component, such  as |
// | this, is also licensed under the GPL license.                               |
// +-----------------------------------------------------------------------------+
// | For commercial use please contact the Author                                |
// +-----------------------------------------------------------------------------+
// | Author: Richard Thomas <lists"AT"cyberlot"DOT"net>                          |
// +-----------------------------------------------------------------------------+
*/




$.jqpie_tsort = function(span, options) {
  oTable = document.createElement('TABLE');
  oTable.id = span.id+'tbl';
  $(oTable).addClass(options.tclass);
  build_header(oTable);
  if(options.per_page) {
    options.pages = Math.ceil(options.data['data'].length / options.per_page);
    build_pages(oTable);
  }
  build_body(oTable);
  span.appendChild(oTable);
  options.table = oTable;
  rebuild_body(oTable);



  function rebuild_body() {
    oTable = options.table;
    rows = oTable.tBodies[0].childNodes.length;
	  for(j = 0; j < rows; j++) {
		  oTable.tBodies[0].deleteRow(0);
	  }
    data = options.data['data'];
    if(options.per_page) {
    	ndata = data.slice( (options.page - 1) * options.per_page, options.per_page * options.page);
    }
	  for(j = 0; j < ndata.length; j++) {
		  current_row = document.createElement("TR");
		  for(i = 0; i < oTable.cols; i++) {
			  current_cell = document.createElement("TD");
        txt = ndata[j][i];
        if(options.data['callbacks'][i]) {
          func = options.data['callbacks'][i];
          try {
//          alert(func);
//          txt = window[func](txt);
          } catch(err) {
            alert(err);
          }
        }
	  		current_cell.innerHTML = txt;
		  	current_row.onmouseout=function() {this.className='';return false }
			  current_row.onmouseover=function() {this.className='ruled';return false }
			  current_row.appendChild(current_cell);
  		}
	  	oTable.tBodies[0].appendChild(current_row);
  	}

  }

  function tableresort(cell) {
    data = options.data['data'];
    sortby = cell.row;
    sorttype = options.data['sorts'][sortby];
  	data = sort_data( data , sortby, sorttype, cell.sort );
    options.data['data'] = data;
  	rebuild_body( );
    if(cell.sort) {
      cell.sort = 0;
    } else {
      cell.sort = 1;
    }
  }

  function build_body(table) {
    oTBody = document.createElement('TBODY');
    table.appendChild(oTBody);
  }

  function build_header(table) {
    oTHead = document.createElement('THEAD');
    oRow = document.createElement("TR");
    headers = options.data['headers'];
    for(j = 0; j < headers.length; j++) {
      oCell = document.createElement("TH");
      oCell.innerHTML = headers[j];
      oCell.row = j;
      oCell.sort = 0;
      $(oCell).click(function() { tableresort(this); });
      oRow.appendChild(oCell);
    }
    oTHead.appendChild(oRow);
    table.appendChild(oTHead);
    table.cols = j;
  }

  function build_pages(table) {
    $('.'+span.id+'_pages').each(function() {
      ul = document.createElement('UL');
      for(j = 0; j < options.pages; j++) {
        li = document.createElement('LI');
        li.innerHTML = j + 1;
        li.j = j;
        $(li).click(function() { options.page = this.j + 1; rebuild_body(); });
        ul.appendChild(li);    
      }
      this.appendChild(ul);
    });
  }

  function sort_data( indata, sortby, sorttype, sortdir ) {
  	var strdat = indata[1][sortby]
  	sortkey = sortby;
  	dirkey = sortdir;
  	sortfn = alphasort;
  	switch( sorttype ) {
  		case 'alphasort':
  			sortfn = alphasort;
  			break;
  		case 'numsort':
  			sortfn = numsort;
  			break;
  	}
  	indata.sort( sortfn );
  	return indata;
  }


  function numsort(a,b) {
    if(dirkey == 1) {
		  aa = a[sortkey];
	    bb = b[sortkey];
	  } else {
		  aa = b[sortkey];
	    bb = a[sortkey];
	  }
    if (isNaN(aa)) aa = 0;
    if (isNaN(bb)) bb = 0;
    return aa-bb;
  }


  function alphasort(a,b) {
  	if(dirkey == 1) {
  	  aa = a[sortkey].toLowerCase();
  	  bb = b[sortkey].toLowerCase();
	  } else {
	    aa = b[sortkey].toLowerCase();
	    bb = a[sortkey].toLowerCase();
	  }
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
  }


}

$.fn.jqpie_tsort = function(options) {
// Make sure options exists
  options = options || {};
// Set default values for required options
  options.tclass = options.tclass || 'jqpie_tsort';
  options.per_page = options.per_page || 0;
  options.page = options.page || 1;
  this.each(function() {
    var input = this;
    $.getJSON(options.url, { handler: 'json', callback: options.callback }, function(json) {  options.data = json; new $.jqpie_tsort(input, options); }); 

  });

  // Don't break the chain
  return this;
}
    

