﻿///// COMMON


///////////////////////////////////////////////////////////////////////////////
/*                             DOM RELATED                                   */ 
///////////////////////////////////////////////////////////////////////////////

//Removed an element from its parent
//function removeElement(id)
//{
//  var e = $(id);
//  if (e!=null)
//  {
//    var p = e.parentNode || e.parentElement;
//    if (p!=null)
//      p.removeChild(e);
//  }
//}

if (!document.selection && typeof(HTMLElement)!="undefined")
{
  HTMLElement.prototype.__defineSetter__("innerText", function (sText) {
     this.innerHTML = sText.replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  });
}

function sanitize(text)
{
  return String(text).stripTags();
  var d = document.createElement("DIV");
  d.innerHTML = text;
  return d.innerText || d.textContent;
}

function emptyElement(elem)
{
  if (!elem)
    return;
  var c = elem.firstChild,d;
  while(c)
  {  
    d = c.nextSibling;
    elem.removeChild(c);
    c = d;
  }  
}

function hashToUrl(obj)
{
  return $H(obj).toQueryString();
}

function addScript(url,id)
{
  var s = document.createElement('SCRIPT');
  s.type = 'text/javascript';
  s.src = url;
  s.id = id;
  s.charset ='utf-8';
  document.body.appendChild(s);
}

function createElement(type, props, children)
{
  var ret = document.createElement(type);
  if (props)
  {
    for (var i in props)
    {
      if (props.hasOwnProperty(i))
      {
        if (i=="style")
          ret.cssText = props[i];
        else
          ret[i] = props[i];
      }
    }
  }
  if (children)
  {
    for (var i=0,j=children.length;i<j;i++)
    {
      ret.appendChild(children[i]);
    }
  }
  return ret;
}

function setHomepage(url,title)
{
  title = title||document.title;
  try
  {
    document.body.style.behavior='url(#default#homepage)';
    document.body.setHomePage(url);
    return true;
  } 
  catch(e1)
  {
  }
  
  try
  {
    if (window.external && window.external.AddFavorite)
    {
      window.external.AddFavorite(url,title);
      return true;
    }
  } 
  catch(e2)
  {
  }
  
  try
  {
    if (window.sidebar)
    {
      if(window.netscape)
      {
        try
        {  
              netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        }  
        catch(e)  
        {  
          //alert("this action was aviod by your browser，if you want to enable，please enter about:config in your address line,and change the value of signed.applets.codebase_principal_support to true");  
          //netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite'); 
          //navigator.preference('signed.applets.codebase_principal_support', true);
          //navigator.preference('browser.startup.homepage', url);
        }
      } 
      var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components. interfaces.nsIPrefBranch);
      prefs.setCharPref('browser.startup.homepage',url);    
      return true;
    }
  }
  catch(e3)
  {
  }
  return false;
}

function addBookmark(url,title)
{
  title = title||document.title;
  try
  {
      if (window.sidebar) 
      { // Mozilla Firefox Bookmark
		    window.sidebar.addPanel(title, url,"");
	    } 
	    else if (window.external)
	    { // IE Favorite
		    window.external.AddFavorite(url, title); 
		  }
	    else if (window.opera && window.print) 
	    { // Opera Hotlist
		    return true; 
		  }
  } catch(e)
  {
  }
  return false;
}


///////////////////////////////////////////////////////////////////////////////
/*                           SEARCH RELATED                                  */ 
///////////////////////////////////////////////////////////////////////////////

var searchPending = false;
var searchEnginesPending = [];
var loaded = false;
var searchResultsToShow = 16;
var searchResults = {current:0};
var searchEngines = {count:0,data:{}};

// Once everything is loaded, allow the search button, and search if a request is pending
function allowSearching()
{
  loaded = true;
  for(var i=0;i<searchEnginesPending.length;i++)
    RegisterSearchEngine(searchEnginesPending[i]);
  RegisterSearchEngine = function(){};
  
  if (searchPending)
  {
    searchPending = false;
    doSearchNow();
    return;
  }
  var qa = new Querystring();
  var term = qa.get("q");  
  var st = new TabControl("SearchType");
  st.OnSelectionChanged = refreshAdvancedMode;
  var searchType = qa.get("searchType");
  if (searchType)
    st.SetValue(searchType);
  var adv = qa.get("advanced")=="true";
  if (adv)
    advancedMode();
    
  var checkedEngines = qa.get("engines");
  if (checkedEngines)
  {
    setEngines(checkedEngines);
  }
    
  
  $('searchTb').focus(); 
}

function refreshAdvancedMode(sel)
{
  webAdv = $('advancedWeb');
  imgAdv = $('advancedImg');
  if (sel.value == "image")
  {
    if (webAdv.style.display!="none")
    {
      imgAdv.style.display = webAdv.style.display;
      webAdv.style.display = "none";
    }
  }
  if (sel.value == "web")  
  {
    if (imgAdv.style.display!="none")
    {
      webAdv.style.display = imgAdv.style.display;
      imgAdv.style.display = "none";
    }
  }  
}

function setEngines(checkedEngines)
{
  checkedEngines = checkedEngines.split(",");
  for(var i in searchEngines.data)
    searchEngines.data[i].Disable();    
  
  for(var i=0;i<checkedEngines.length;i++)
  {
    if (searchEngines.data[checkedEngines[i]])
    {
          searchEngines.data[checkedEngines[i]].Enable();
    }
  }
}

function advancedMode()
{
  var advancedDiv = null;
  if ($('WebSearchCb').checked)
    advancedDiv = $('advancedWeb');
  else if ($('ImageSearchCb').checked)
    advancedDiv = $('advancedImg');


  var toAdv =  advancedDiv.style.display=='none';
//  if (advancedDiv._effect)
//    advancedDiv._effect.Stop();
//  if (toAdv)
//  {    
//    advancedDiv._effect = Effect.BlindDown(advancedDiv.id);
//  }
//  else
//  {
//    advancedDiv._effect = Effect.BlindUp(advancedDiv.id);
//  }
  advancedDiv.style.display= toAdv ? '' : 'none';
  var ftn = getFirstTextNode($('advancedToggle'));
  ftn.nodeValue = toAdv ? 'Basic' : 'Advanced';
  $('searchTb').focus();
}

function getFirstTextNode (n)
{
  var ret = null;
  var siblings = $A(n.childNodes).each(function(t)
  {
    if (ret!=null)
      return;
    if (t.nodeType == 3 && !t.nodeValue.blank())
      ret = t;
    else if (t.nodeType == 1)
      ret = getFirstTextNode(t);
  });
  return ret;
}

// Logs the process of a search engine
function logProgress(engine,progress)
{
  var engineData = searchEngines.data[engine];
  if (engineData)
    engineData.progressCtrl.reportProgress(progress);
}

String.prototype.Trim = function(s) 
{
  s = s || this;
  s = s.replace(/\s*((\S+\s*)*)/, "$1");
  s = s.replace(/((\s*\S+)*)\s*/, "$1");
	return s;
}

function getCheckedEngines()
{
  var ce = [];
  for(var i in searchEngines.data)
    if (searchEngines.data[i].IsEnabled())
    {
      ce.push(i);
    }
  return ce.join(",");
}

function getAdvancedOptions()
{
  var opts = {};
  if ($('WebSearchCb').checked)
  {
    opts.searchType = "web";
    opts.ilang =  $('ILanguageSb').value;
    opts.lang =  $('LanguageSb').value;
    opts.country = $('CountrySb').value;
    opts.advanced = $('advancedWeb').style.display!="none";  
  }
  else if ($('ImageSearchCb').checked)
  {
    opts.searchType = "image";
    opts.adult_ok= $('AdultOk').checked;
    opts.colorOnly= $('ImageColoration').value=="Color Only";
    opts.blackWhiteOnly= $('ImageColoration').value=="B&W Only";
    opts.format = $('ImageFormat').value;
    opts.advanced = $('advancedImg').style.display!="none";  
  }
  return opts;
}

function doSearch()
{
  term = $('searchTb').value;
  var opts = getAdvancedOptions();  
  opts.engines = getCheckedEngines();
  //opts.q = term;
  //if ($('advancedToggle').style.display=='none')
  //  opts.adv = "true";
  var href = "?q="+encodeURIComponent(term)+"&"+hashToUrl(opts);
  location.href = href;
}

function resizeRect(h,w,maxh,maxw)
{
  var candidates = [];
  if (h > 0 && w > 0)
  {  
    var oh=h, ow=w, hwRatio = h/w;
    if (h > maxh)
    {
      h = maxh;
      w = h / hwRatio;
    }
    if (w > maxw)
    {
      w = maxw;
      h = w * hwRatio;
    }
    candidates.push({height:h, width:w, rank: w*h});
    h = oh; w = ow;    
    if (w > maxw)
    {
      w = maxw;
      h = w * hwRatio;
    }
    if (h > maxh)
    {
      h = maxh;
      w = h / hwRatio;
    }
  }
  candidates.push({height:h, width:w, rank: w*h});
  candidates.sort(function(a,b){return a.rank-b.rank;});
  return candidates[0];;
}


function doSearchNow(term)
{
  if (!loaded) { searchPending = true; return; }
  term = term || $('searchTb').value;
  if (term.Trim().length==0)
  {
    alert('Please enter a search term');
    return;
  }
  term = term.Trim();
  var id = new Date().valueOf();            
  searchResults.current = id;   
  
  var activeEngines = 0;  
  for(var i in searchEngines.data)
  {
    if (searchEngines.data[i].IsEnabled())
    {
      searchEngines.data[i].DoSearch(term,id,getAdvancedOptions());
      activeEngines++;
    }  
  }
  
  var asq = new AutoSuggestQuery(term,15);
  asq.completionData = {
    onSuccess : function(results)
    {
      suggestRelatedQueries(results);
      //Build tag cloud / Did you mean / Related searches
      
    }
  }
  
    
  if (activeEngines==0)
  {
    alert("Please select some search engines to search in.");    
  }    
}

function suggestRelatedQueries(suggestions)
{
  if (!suggestions || !(suggestions.length))
  {
    return;
  }
  
  $('ReleatedSearchesTable').style.display = "";
  var elem;
  for(var i=0,j=suggestions.length;i<j;i++)
  {
    if (i%5 == 0)
    {
      elem = $('ReleatedSearches'+String((i/5)+1));  
      if (!elem)
        return;
      elem.style.padding = "2px";
    }
    var sug = suggestions[i].value;
    var d = document.createElement('DIV');
    var a = $(document.createElement('A'))
    a.href="javascript:void(0)";
    a.innerText = sug;
    a.observe('click', SearchRelatedTerm.curry(sug));
    d.appendChild(a);
    elem.appendChild(d);
  }
}
function SearchRelatedTerm(txt)
{
  $('searchTb').value = txt;
  doSearch();
}
function CreateProgressTable()
{
  var engineProgressTbl = document.createElement("TABLE");
  engineProgressTbl.cellSpacing = "0px";
  engineProgressTbl.cellPadding = "0px";
  engineProgressTbl.style.width = "100%";  
  var tbody = document.createElement("TBODY");      
  engineProgressTbl.appendChild(tbody);
  var tr = document.createElement("TR");
  tr.style.height="5px";
  tbody.appendChild(tr);
  var cell1 = document.createElement("TD");
  cell1.innerHTML = "<div/>";//<img src='Images/blank.gif'>";
  cell1.style.width="0%";
  cell1.style.backgroundColor="black";
  var cell2 = document.createElement("TD");
  cell2.innerHTML = "<div/>";//"<img src='Images/blank.gif'>";
  cell1.style.width="100%";
  cell2.style.backgroundColor="gray";
  tr.appendChild(cell1);
  tr.appendChild(cell2);
  
  engineProgressTbl.reportProgress = function(progress)
  {
    if (progress=='done')
    {   
      cell1.style.width="100%";   
      cell2.style.width="0%";
    }
    else
    {
      progress = progress*100;
      cell1.style.width=progress+"%";
      cell2.style.width=(100-progress)+"%";
    }
  }
  
  return engineProgressTbl;
}    

function RegisterSearchEngine(searchEngine)
{
  if (!loaded)
  {
    searchEnginesPending.push(searchEngine);
    return;
  }  
  var rp = new ResultsPanel(searchEngine);
  searchEngines.data[searchEngine.name] = rp;
  rp.Initialize();
}

function Register(engineURL)
{
  engineURL= engineURL || "http://www.searchall.com/getallresult.xml";
  try
  {
    window.external.AddSearchProvider(engineURL)
  }
  catch(e)
  {
    alert('Installation failed.');
  }
}  


/* Client-side access to querystring name=value pairs
	Version 1.3
	28 May 2008
	
	License (Simplified BSD):
	http://adamv.com/dev/javascript/qslicense.txt
*/
function Querystring(qs) { // optionally pass a querystring to parse
	this.params = {};
	
	if (qs == null) qs = location.search.substring(1, location.search.length);
	if (qs.length == 0) return;

// Turn <plus> back to <space>
// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
	qs = qs.replace(/\+/g, ' ');
	var args = qs.split('&'); // parse out name/value pairs separated via &
	
// split out each name=value pair
	for (var i = 0; i < args.length; i++) {
		var pair = args[i].split('=');
		var name = decodeURIComponent(pair[0]);
		
		var value = (pair.length==2)
			? decodeURIComponent(pair[1])
			: name;
		
		this.params[name] = value;
	}
}

Querystring.prototype.get = function(key, default_) {
	var value = this.params[key];
	return (value != null) ? value : default_;
}

Querystring.prototype.contains = function(key) {
	var value = this.params[key];
	return (value != null);
}

///////////////////////////////////////////////////////////////////////////////
/*                             Paging Control                                */ 
///////////////////////////////////////////////////////////////////////////////

function PagingControl(div, pages, callback)
{
  this.Container = $(div);
  this.pageCount = pages;
  this.callback = callback;
  this.pagesToShow = 9;
  this.Setup();  
  this.SelectPage(1); 
}

PagingControl.prototype.ReInitialize = function(pages,callback)
{
  for (var i=0;i<this.cells.length;i++)
  {
    this.tr.removeChild(this.cells[i]);
    this.cells[i].onclick = null;
  }
  this.pageCount = pages;
  this.callback = callback || this.callback;
  this.BuildCells();
  this.SelectPage(1,true);
}

PagingControl.prototype.Setup = function()
{
  var tbl = document.createElement("TABLE");
  tbl.className = "pagerTable";
  tbl.cellSpacing = 1;
  tbl.cellPadding = 0;
  this.Container.appendChild(tbl);
  var tbody = document.createElement("TBODY");
  tbl.appendChild(tbody);
  var tr = document.createElement("TR");
  this.tr = tr;
  tbody.appendChild(tr);
  this.BuildCells();
}

PagingControl.prototype.BuildCells = function()
{
  this.cells = [];
  var cellCount = Math.min(this.pagesToShow, this.pageCount);
  this.currentPage = 0;
  var me = this;
  for (var i=0;i<cellCount;i++)
  {
    var td = document.createElement("TD");
    this.tr.appendChild(td); 
    td.onclick = function()
    {
      me.SelectPage(this.value);
    }         
    this.cells.push(td);
  }
}

PagingControl.prototype.SelectPage = function(page, preventCallback)
{
  this.currentPage = page;
  
  var firstPage = Math.ceil(Math.max(page-(this.pagesToShow)/2,1));
  var lastPage = Math.ceil(Math.min(firstPage+this.pagesToShow-1,this.pageCount));
  
  if (lastPage - firstPage + 1 < this.cells.length)
  {
    firstPage = Math.max(lastPage - this.cells.length + 1,1);
  }
  
  for (var i=firstPage, j=0;i<=lastPage;i++,j++)
  {
    var cell = this.cells[j];
    var str = i.toString();
    if(i==page)
    {
      //if (i>firstPage)
        //str = "&raquo;"+str;
      //if (i < lastPage)
        //str = str+"&laquo;";
        cell.className = "pagerSelected" ;
    }
    else  
    {
      cell.className = "pagerUnselected";
    }
    //str = "<a href='javascript://' onclick='this.parentElement.click()'>"+str+"</a>";
    if (cell.value!=i)
    {
      cell.innerHTML = str;
      cell.value = i;
    }
  }  
  if (this.callback && !preventCallback)  
    this.callback(page);
}

///////////////////////////////////////////////////////////////////////////////
/*                             Search Engine Model                           */ 
///////////////////////////////////////////////////////////////////////////////

//A SearchEngine is a factory for Search objects. It represents a single web search engine.
function SearchEngine(data)
{
  this.name = data.name;
  this.desc = data.desc;
  this.imageUrl = data.imageUrl;
  this.searchFunc = data.searchFunc;  
}
SearchEngine.prototype.Register = function()
{
  RegisterSearchEngine(this); 
}
// To be overridden by instantiated classes
SearchEngine.prototype.CreateSearch = function(term, id, options)
{
  return new Search(this, term, id, options);
}

// A Search object is created by an engine to process a search response for a single term and multiple pages
function Search(engine, term, id, options)
{
  this.engine = engine;
  this.term = term;
  this.id = id;
  this.Pages = [];
  
  if (options)
    for(var on in options)
      if (options.hasOwnProperty(on))
        this[on] = options[on];
}
Search.prototype.GetPage = function(pageNumber, pageReadyCallback, notifyEstimatesCallback)
{
  //Save these for later requests, so that they can be cached internally
  pageReadyCallback = pageReadyCallback || this.pageReadyCallback;
  if (pageReadyCallback)
    this.pageReadyCallback = pageReadyCallback;
  
  notifyEstimatesCallback = notifyEstimatesCallback || this.notifyEstimatesCallback;
  if (notifyEstimatesCallback)
    this.notifyEstimatesCallback = notifyEstimatesCallback;
  
  if (this.Pages[pageNumber] && this.Pages[pageNumber].isReady)
  {
    var id = this.id;
    (function()
    {
      if (pageReadyCallback)
        pageReadyCallback(id, pageNumber);
    }).delay(0);
  }
  else
  {  
    this.InternalGetPage(pageNumber, pageReadyCallback, (pageNumber==1 && notifyEstimatesCallback));
  }
}

function appendHighlightedContents(elem, txt, words)
{ 
  elem.appendChild(document.createTextNode(txt));
  var iHtml = elem.innerHTML;
  var lHtml = iHtml.toLowerCase();
  var highlightIdx = [];
  
  for(var i=0,j=words.length;i<j;i++)
  {
    var lwrd = words[i].toLowerCase();    
    var ll = lwrd.length;
    var temp = lHtml.split(lwrd);
    if (temp.length==1)
      continue;
    var idx = 0;
    for (var k=0,l=temp.length;k<l;k++)
    {
      idx += temp[k].length;
      highlightIdx.push({len:ll, idx:idx});
      idx += ll;
    }
  }
  if (highlightIdx.length>0)
  {
    highlightIdx.sort(function(a,b){return a.idx-b.idx;});
    var idx = 0;
    var sb = [];
    for (var i=0,j=highlightIdx.length;i<j;i++)
    {
      var p = highlightIdx[i];
      if (p.idx>0)
      {
        sb.push(iHtml.substr(idx,p.idx-idx));
        idx = p.idx;
      }
      sb.push("<span class='wordHighlight'>"+iHtml.substr(p.idx,p.len)+"</span>");
      idx += p.len;
    }
    iHtml = sb.join('');
  }
  
  elem.innerHTML = iHtml;
}

function ResultsPanel(engine)
{
  this.engine = engine;
  this.initialized = false;
  this.isShown = false;
  this.nameShown = false;
}

ResultsPanel.prototype.Clear = function()
{
  emptyElement(this.dataTd);
}

ResultsPanel.prototype.DoSearch = function(term,id, options)
{
  if (!this.nameShown)
  {
    this.nameTh.style.display = "";
    this.nameShown = true;
  }
  this.Clear();
  if (this.estimationTitle!=null)
  {
    $(this.estimationTitle).up().style.display="";
    this.estimationTitle.innerHTML = "Searching...";
  }
  //.innerHTML = ""; //Clear estimation title  
  this.PageNumber = 1;
  //this.progressTable.style.display = "";
  this.Search = this.engine.CreateSearch(term,id,options);
  this.Search.GetPage(1, this.PageReadyCallback.bind(this), this.NotifyEstimationCallback.bind(this));    
}
ResultsPanel.prototype.CreateItemCell = function(item,searchType,words)
{
  switch(searchType)
  {
    case "image":
      return this.CreateImageItemCell(item,words);
    case "web":
      return this.CreateWebItemCell(item,words);
  }
}

ResultsPanel.prototype.CreateImageItemCell = function(item,words)
{
  var div = document.createElement('DIV');
  div.className = 'result imageResult';
  if (item.message)
  {
    div.innerHTML = item.message;
    return div;
  }  
  
  var title = document.createElement('A');
  title.className = 'title';
  title.href = item.ClickUrl;
  var img = document.createElement('IMG');
  img.src = item.ThumbnailUrl;  
  
  var oh = item.ThumbnailHeight, ow = item.ThumbnailWidth;
  var newDim = resizeRect(oh, ow, 150,200);
  img.style.width = newDim.width+"px";
  img.style.height = newDim.height+"px";
  
  img.style.border = "0px";
  title.appendChild(img); 
  title.appendChild(document.createElement('BR'));
  div.appendChild(title);
  
  
  //var description = document.createElement('DIV');
  //description.className = 'description imageDescription';
  //appendHighlightedContents(description, this.FormatEllipsis(item.Text || item.Summary,50).stripTags(), words);
  //description.innerHTML = this.FormatEllipsis(item.Text || item.Summary,50);
  title.title = (item.Text || item.Summary).stripTags();
  //title.appendChild(description);
  
  var metadata = document.createElement('DIV');
  metadata.className = 'imageMetadata';
  metadata.innerHTML = this.FormatImageMetadata(item);  
  div.appendChild(metadata);
  return div;
}

ResultsPanel.prototype.FormatImageMetadata = function(item)
{
  var ret = [];
  ret.push(item.Width);
  ret.push("x");
  ret.push(item.Height);
  
  if (item.FileSize)
  {
    ret.push(" ");
    var units = "Kb";
    var sz = item.FileSize / 1024;
    if (sz > 1048)
    {
      sz = sz / 1024;
      units = "Mb";
    }
    if (sz > 1048)
    {
      sz = sz / 1024;
      units = "Gb";
    }
    if (String(sz).length>7)
    {
      sz = Math.floor(sz*100) / 100;      
    }
    
    ret.push(sz);
    ret.push(" ");
    ret.push(units);
  }
  if (item.FileFormat)
  {
    ret.push(" ");
    ret.push(item.FileFormat);
  }
  
  return ret.join('');
}

ResultsPanel.prototype.CreateWebItemCell = function(item,words)
{
  var div = document.createElement('DIV');
  div.className = 'result';
  
  var title = document.createElement('A');
  title.className = 'title';
  title.innerHTML = (item.clearTitle || item.title).stripTags();
  
  div.appendChild(title);
  title.href = item.url;
  
  var description = document.createElement('DIV');
  description.className = 'description';
  appendHighlightedContents(description, item.description.stripTags(), words);
  //description.appendChild(document.createTextNode(page[i].description));
  description.title = item.description;
  div.appendChild(description);
  
  var url = document.createElement('DIV');
  url.className = 'url';
  var urlText = item.visibleUrl || item.url;
  urlText = this.FormatEllipsis(urlText.stripTags(),50);  
  url.appendChild(document.createTextNode(urlText));
  div.appendChild(url);   
  return div;
}
ResultsPanel.prototype.FormatEllipsis = function(txt, len)
{
  if (txt && txt.length>len)
    txt = txt.substring(0,len-3)+"...";
  return txt;
}
ResultsPanel.prototype.PageReadyCallback = function(id, pageNumber)
{
  if (!this.isShown)
    this.Show();  
  if (this.Search && this.Search.id == id && pageNumber == this.PageNumber)
  { 
    this.Clear();
    var page = this.Search.Pages[pageNumber];
    var words = [];
    if (page.length==0 && pageNumber==1)
    {
      page.push({message:"No Results were found", title:"", url:"", description: "No Results were found", urlText:""});
    }
    else
    {
      words = this.Search.term.split(' ');
    }    
    for (var i=0,j=page.length;i<j;i++)
    {          
      var div = this.CreateItemCell(page[i], this.Search.searchType, words);             
      this.dataTd.appendChild(div);          
    }
    if (this.pc.pageCount>1)
      this.dataTd.appendChild(this.pcContainer);    
    
    //Display results
    //this.progressTable.style.display = "none";    
  }
}

ResultsPanel.prototype.NotifyEstimationCallback = function(id, estimation, usableResultEstimation)
{
  if (!this.isShown)
    this.Show();
  if (this.Search && this.Search.id == id)
  {
    //Display estimates
    if (this.estimationTitle!=null)
    {
      var estText = parseInt(estimation).toString();
      var i=estText.length%3;
      if (i==0)
        i = 3;
      while(i<estText.length)
      {
        estText = estText.substr(0,i)+","+estText.substr(i);
        i+=4;
      } 
      $(this.estimationTitle).up().style.display = "";
      if (estText=="0")
        estText = "no";
      this.estimationTitle.innerHTML = estText+" results";
    }
    if (!usableResultEstimation)
      usableResultEstimation = estimation;
    
    var pages = Math.ceil(usableResultEstimation / searchResultsToShow);
    this.pc.ReInitialize(pages);
    if (pages<2)
    {
      var container = $(this.pc.Container);
      if (container && container.parentElement!=null)
        $(this.pc.Container).remove();
    }
  }
}

ResultsPanel.prototype.ShowWaitingImage = function()
{    
    var img = this.waitingImage;
    if (!img)
    { 
      this.waitingImage = img = new Image(); 
      img.src = "Images/ajax-loader.gif";
    }
    this.dataTd.appendChild(img);
}

ResultsPanel.prototype.NaviageToPage = function(page)
{
  if (this.Search)
  {
    //this.progressTable.style.display = "";
    this.Clear();
    this.ShowWaitingImage();        
    this.PageNumber = page;
    this.Search.GetPage(page);
  }
}
ResultsPanel.UniqueIDs = 0;
ResultsPanel.prototype.Initialize = function()
{
  if (this.initialized)
    return;
  this.initialized = true; 
  var engineData = $('engineData'); //REFACTOR ID 'engineData'
  var engineDataRow;
  if (engineData.rows.length==0)
  {
    engineDataRow = createElement("TR");
    engineData.appendChild(engineDataRow)
  }
  else
    engineDataRow = engineData.rows[0];
  
  this.nameTh = document.createElement("TH");      
  this.nameTh.className = "engineResults";
  this.nameTh.style.display = "none";
  this.nameTh.style.height = "25px";
  this.nameTh.style.verticalAlign = "top";
  
  //Create title
  if (this.engine.imageUrl)
  {
    this.nameTh.appendChild(createElement("IMG",{src:this.engine.imageUrl,title: this.engine.desc}));    
  }
  else
  {
    this.nameTh.appendChild(createElement("B",{innerHTML:this.engine.name}));
  }
  //this.nameTh.appendChild(createElement("BR"));
  //$('SearchEstimations').innerHTML += "<div>"+this.engine.name+": "+estimation+" results</div>"
  var se = $('SearchEstimations');
  if (se!=null)
  {
    var tr = createElement("TR");
    var td1 = createElement("TD");
    td1.innerHTML = this.engine.name+": ";
    this.estimationTitle = createElement("TD");
    tr.appendChild(td1);
    tr.appendChild(this.estimationTitle);
    tr.style.display="none";
    se.appendChild(tr);    
  }
  
  //Create search engine enabler
  this.cb = createElement("INPUT", {type:"CheckBox"});  
  this.cb.id = "toggle_"+this.engine.name;
  $('engineEnablers').appendChild(this.cb);
  var lbl = document.createElement("LABEL");
  lbl.htmlFor = this.cb.id;  
  lbl.setAttribute("for",this.cb.id);
  lbl.appendChild(document.createTextNode(this.engine.name));
  $('engineEnablers').appendChild(lbl);
  //$('engineEnablers').appendChild(createElement("BR"));
  
  this.cb.checked = true;
  
  //Create progress bar
//  this.progressTable = CreateProgressTable();
//  this.progressTable.reportProgress(0);
//  this.progressTable.style.display = "none";
//  this.nameTh.appendChild(this.progressTable);
  
  engineDataRow.appendChild(this.nameTh);
  
  var engineResults = $('resultsBody');
  var engineResultsRow;
  if (engineResults.rows.length==0)
  {
    engineResultsRow = createElement("TR");
    engineResults.appendChild(engineResultsRow)
  }
  else
    engineResultsRow = engineResults.rows[0];
  this.dataTd = document.createElement("TD");
  this.dataTd.style.display = "none";
  this.dataTd.style.verticalAlign = "top";
  engineResultsRow.appendChild(this.dataTd);
  
  this.pcContainer = createElement("DIV");  
  this.pc = new PagingControl(this.pcContainer,1,this.NaviageToPage.bind(this));
}

ResultsPanel.prototype.Show = function()
{
  //this.nameTh.style.display = "";
  this.dataTd.style.display = "";
  this.isShown = true;
}

ResultsPanel.prototype.Hide = function()
{
  //this.nameTh.style.display = "none";
  this.dataTd.style.display = "none";
  this.isShown = false;
}


ResultsPanel.prototype.IsEnabled = function()
{
  return this.cb.checked;
}

ResultsPanel.prototype.Enable = function()
{
  this.cb.checked = true;
}

ResultsPanel.prototype.Disable = function()
{
  this.cb.checked = false;
}


function notifyEngineResultsEstimation(engine, id, count, count2)
{
  var sed = searchEngines.data[engine];
  if (!sed) return;
  var search = sed.Search;
  if (!search) return;
  if (search.id != id)
    return;
  search.notifyEstimatesCallback(id, count, count2);
}

function notifyEngineResults(engine, id, results, offset, hasMore)
{
  var sed = searchEngines.data[engine];
  if (!sed) return;
  var search = sed.Search;
  if (!search) return;
  if (search.id != id)
    return;
  var pageOffset = offset % searchResultsToShow;
  var pageNumber = 1 + ((offset-pageOffset) / searchResultsToShow);
  if (!search.Pages[pageNumber])
    search.Pages[pageNumber] = [];
    
  var searchPage = search.Pages[pageNumber];
  var currentPageNumber = pageNumber;
  for(var i=0;i<results.length;i++)
  {
    if (i+pageOffset==searchResultsToShow)
    {
      currentPageNumber++;
      if (!search.Pages[currentPageNumber])
        search.Pages[currentPageNumber] = [];
      searchPage = search.Pages[currentPageNumber];
      pageOffset=i*-1;      
    }
    searchPage[i+pageOffset] = results[i];
  }
  searchPage = search.Pages[pageNumber];
  var resultsInPage = searchPage.length;
  if (resultsInPage == searchResultsToShow || !hasMore)
  {
    searchPage.isReady = true;
    (function(){search.pageReadyCallback(id, pageNumber);}).delay(0);
  }
}


/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/

var Url = {

	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

/*************************************************************************************/
/*                                  AutoSuggest                                      */
/*************************************************************************************/
if (typeof(window.google)=='undefined')
  window.google = {};
window.google.ac = {};
window.google.ac.Suggest_apply = function(frameelement,term,suggestsions,more)
{
  var q = AutoSuggestQuery.current;
  if (q && !q.abort && q.term==term)
  {
    var s = [];
    for(var i=1;i<suggestsions.length-1;i+=2)
    {
      s.push({value:suggestsions[i]});//,info:suggestsions[i+1]});
    }  
    q.notifyResults('Google',s);
    
   //$('AutoSuggestQuery_Google_'+q.id).remove.delay(0);
  }
}
window.live = {};
window.live.ac = {};
window.live.ac.Callbacks = {};
window.live.ac.CreateCallback = function(id)
{
  
  window.live.ac.Callbacks[id] = function(results)
  {   
    var q = AutoSuggestQuery.current;
    if (q && !q.abort && q.id==id)
    {
      var s = [];
      if (results && results.SearchResponse && results.SearchResponse.RelatedSearch && results.SearchResponse.RelatedSearch.Results)
      {
        var r = results.SearchResponse.RelatedSearch.Results;  
        for (var i=0;i<r.length;i++)
        {
          s.push({value:r[i].Title});
        }
      }
      if (results && results.SearchResponse && results.SearchResponse.Spell && results.SearchResponse.Spell.Results)
      {
        var r = results.SearchResponse.Spell.Results;  
        for (var i=0;i<r.length;i++)
        {
          s.push({value:r[i].Value});
        }
      }      
      q.notifyResults('Live',s);
    }
  }
}

window.yahoo = {};
window.yahoo.ac = {};
window.yahoo.ac.Callbacks = {};
window.yahoo.ac.CreateCallback = function(id)
{
  window.yahoo.ac.Callbacks[id] = function(results)
  {    
    var q = AutoSuggestQuery.current;
    if (q && !q.abort && q.id==id)
    {
      var r = results && results.ResultSet && results.ResultSet.Result;
      var r2=[];
      if (r)
      {
        if (typeof(r)=='string')
        {
          r2.push({value:r});
        }
        else
        {
          for (var i=0;i<r.length;i++)
            r2.push({value:r[i]});
        }
      };
      q.notifyResults('Yahoo',r2);
      (function(){
        window.yahoo.ac.Callbacks[id] = null;
      }).delay(0);
    }
  }
}
window.yahoo.ac.Suggest_apply = function(suggestions)
{
  //debugger;
}
var AutoSuggestQuery = Class.create();
AutoSuggestQuery.prototype = {
  initialize : function(term,max)
  {
    if (AutoSuggestQuery.current)
      AutoSuggestQuery.current.abort = true;
    AutoSuggestQuery.current = this;
    this.id = new Date().valueOf();
    this.term = term;
    this.max = max || 10;
    this.results = {};
    //this.searchGoogle();
    this.searchYahoo();
    this.searchLive();
    this.term = decodeURIComponent(this.term);
  },
  
  searchGoogle : function()
  {
    var url = "http://www.google.com/complete/search?hl=en&js=true&q="+this.term;
    var sid = "AutoSuggestQuery_Google_"+this.id;
    addScript.curry(url,sid).delay(0);
    this.results.Google = false;
  },
  
  searchYahoo : function()
  {
    window.yahoo.ac.CreateCallback(this.id);
    var url = "http://search.yahooapis.com/WebSearchService/V1/relatedSuggestion?appid=keIChznV34GJf03Uj6O3C_XWbpAOjEoqZExGlIDZE0ukywtt0zlsYp4DQmBqxI3px9tyJlA1F5OuXg--&output=json&callback=window.yahoo.ac.Callbacks["+this.id+"]&query="+this.term;
    var sid = "AutoSuggestQuery_Yahoo_"+this.id;
    addScript.curry(url,sid).delay(0);
    this.results.Yahoo = false;    
  },
  
  searchLive : function()
  {
    window.live.ac.CreateCallback(this.id);
    var sid = "AutoSuggestQuery_Live_"+this.id;
    var url = "http://api.search.live.net/json.aspx?"
        
            // Common request fields (required)
            + "AppId=5DE6D123674B9E08A96B4E4D1B9ED8F19B53AD34"
            + "&Query="+this.term
            + "&Sources=RelatedSearch+Spell"
            
            // Common request fields (optional)
            + "&Version=2.0"
            + "&Market=en-us"
            //+ "&Options=EnableHighlighting"

            // JSON-specific request fields (optional)
            + "&JsonType=callback"
            + "&JsonCallback=window.live.ac.Callbacks["+this.id+"]";
    addScript.curry(url,sid).delay(0);
    this.results.Live = false;    
  },
  
  notifyResults : function(engine, results)
  {
    if (this.results[engine])
      return;
    this.results[engine] = results;
    for(var i in this.results)
      if (this.results.hasOwnProperty(i) && this.results[i]===false)
        return; //If found an engine that hasn't completed, wait for it
        
    var results = this.joinResults();
    if (this.completionData && this.completionData.onSuccess)
      this.completionData.onSuccess(results);
     
    this.abort = true;
    AutoSuggestQuery.current = null; 
  },
  
  joinResults : function()
  {
    var results = {};
    var resultsLC = {};
    var resultsArr = [];
    for(var engineName in this.results)
    {
      if (this.results.hasOwnProperty(engineName))
      {
        var engineResults = this.results[engineName];
        for (var i=0;i<engineResults.length;i++)
        {
          var value = engineResults[i].value;
          var info = engineResults[i].info && (engineResults[i].info+"("+engineName+")");
          if (resultsLC[value.toLowerCase()])
            value = resultsLC[value.toLowerCase()];
          else
            resultsLC[value.toLowerCase()] = value;
          if (results[value])
          {
            results[value].count++;
          }
          else
          {
            results[value] = {count:1, data: [], value:value};
            resultsArr.push(results[value]);            
          }
          if (info)
              results[value].data.push(info);
        }
      }
    }
    var arr2 = resultsArr.sort(function(a,b) {return (b.count-a.count)*100 + (a.value.length-b.value.length);});
    var arr3 = [];
    for (var i=0;i<arr2.length && i<this.max;i++)
    {
      arr3.push({id:i,value:arr2[i].value,info:arr2[i].data.join(', ')});
    }
    return arr3;
  }
};

Object.extend(AutoSuggestQuery,
{
  current : null
  ,create : function(x){return new AutoSuggestQuery(x);}
  ,abort : function(){if(this.current){this.current.abort=true;this.current=null;};}
});

function searchTbFocus()
{
  AutoSuggestQuery.isShown = false;
  var options = {
		script:AutoSuggestQuery.create//'test.php?json=true&limit=6&'
		,varname:'input'
		//,json:true
		,manualJson:true
		,shownoresults:false
		,maxresults:10
		,timeout : 20000
		,cache:false
		,onChoose : function() 
		{ 		  
		  doSearch.delay(0);
		 }
		//,callback: function (obj) { $('log').update('you have selected: '+obj.id + ' ' + obj.value + ' (' + obj.info + ')'); }
	};
	var json = new AutoComplete('searchTb',options);
	return true;
}

/*

<script type="text/javascript"><!--
google_ad_client = "pub-8180791779577024";
// 120x600, created 9/30/08
google_ad_slot = "1774577800";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

*/

function updateAds(id)
{
  var d=$(id);
	if(d){	
		var s=d.getElementsByTagName('iframe');
		if(s && s.length){
			s[0].src=s[0].src+'&'+new Date().getTime();
		}
	}
}

function updatehighlight()
{
  var cb = $('highlightCb');
  if (!cb)
    return;
  var hl = cb.checked;
  var stylesheet = document.styleSheets[0];
  var rules = stylesheet.rules || stylesheet.cssRules; //CSS RULES!!  
  for (var i=0,j=rules.length;i<j;i++)
  {
    if (rules[i].selectorText=='.wordHighlight')
    {
      rules[i].style.fontWeight = hl ? "bold" : "";
      //rules[i].style.backgroundColor = hl ? "yellow" : "";
      return;
    }
  }
}
