function XPRemoteRequest()
{
    if(window.XMLHttpRequest) return new XMLHttpRequest();
    else if(window.ActiveXObject)
    {
        try { return new ActiveXObject("Msxml2.XMLHTTP"); }
        catch(anException)
        {
            try { return new ActiveXObject("Microsoft.XMLHTTP"); }
            catch(anException) { }
        }
    }
    
    return null;
}

Function.prototype.attach= function(object, context)
{
    var method= this;
    return function() { return method.apply(object, arguments); }
}

function FTBlogSearch()
{
    this.oldSearchValue= "";
    
    this.DOMMainElement= document.getElementById("blog");
    this.DOMSearchElement= document.getElementById("blog-search");
    this.DOMResultsElement= document.getElementById("blog-search-results");
    this.DOMResultsCounterElement= document.getElementById("blog-search-results-counter");
    this.DOMPopulatedElements= new Array();

    this.prepareSearchCallback= this.prepareSearch.attach(this);
    this.updateSearchCallback= this.updateSearch.attach(this);
    this.receiveResultsCallback= this.receiveResults.attach(this);
    
    this.DOMSearchElement.disabled= false;
    this.DOMSearchElement.setAttribute("placeholder", "Search");
    
    this.DOMSearchElement.addEventListener("focus", this.prepareSearchCallback, false);

    var DOMListElement= document.createElement("li");

    this.DOMListElements= new Array(DOMListElement);
    this.DOMListElements.current= 0;
   
    return this;
}

FTBlogSearch.prototype.getOrCreateDOMListElement= function(aTitle, aDate, aTime, aPermalink)
{
    var DOMListElement= (this.DOMListElements[this.DOMListElements.current++]) || 
                        (this.DOMListElements[this.DOMListElements.current-1]= this.DOMListElements[0].cloneNode(true));

    DOMListElement.innerHTML= "<a href=\""+aPermalink+"\"><span class=\"blog-result-time\">"+aTime+"</span><span class=\"blog-result-date\">"+aDate+"</span><span class=\"blog-result-title\">"+aTitle+"</span></a>";
    
    return DOMListElement;
}

FTBlogSearch.prototype.prepareSearch= function()
{
    if(this.DOMSearchElement.value=="" || this.DOMSearchElement.isFireFox && !this.DOMSearchElement.focused)
        window.setTimeout(this.prepareSearchCallback, 400);
    else
    {
        this.DOMMainElement.style.display= "none";
        this.DOMResultsElement.style.display= "block";
        this.DOMResultsCounterElement.style.display= "inline";
        
        this.displayResults([null]);
        
        window.setTimeout(this.updateSearchCallback, 400);
    }
}

FTBlogSearch.prototype.updateSearch= function()
{
    var value= this.DOMSearchElement.value;

    if(this.request && this.request.readyState!=0) this.request.abort();

    if(value=="")
    {
        this.displayResults([null]);
                
        this.DOMMainElement.style.display= "block";
        this.DOMResultsElement.style.display= "none";
        this.DOMResultsCounterElement.style.display= "none";

        window.setTimeout(this.prepareSearchCallback, 400);

        return;
    }
    else if(value!=this.oldSearchValue)
    {
        this.oldSearchValue= value;
            
        this.request= XPRemoteRequest();

        this.request.onreadystatechange= this.receiveResultsCallback;
                
        this.request.open("GET", window.location.href+"?s="+value, true);
        this.request.send(null);
    }
            
    window.setTimeout(this.updateSearchCallback, 800);
}

FTBlogSearch.prototype.receiveResults= function()
{
    if(this.request.readyState!=4) return;
            
    var results= new Array();
    eval(this.request.responseText);
    this.displayResults(results);
}

FTBlogSearch.prototype.displayResults= function(results)
{
    var result,
        i= 0,
        DOMNewlyPopulatedElements= { };

    if(results.length-1==1) this.DOMResultsCounterElement.innerText= "1 Result";
    else this.DOMResultsCounterElement.innerText= (results.length-1)+" Results";

    while(result= results[i++])
    {
        var j= 0,
            category= null,
            categories= result.categories;
  
        while(category= categories[j++])
        {
            if(!DOMNewlyPopulatedElements["category-"+category.UID])
            {
                (DOMNewlyPopulatedElements["category-"+category.UID]= document.getElementById("category-"+category.UID)).innerHTML= "";
                delete this.DOMPopulatedElements["category-"+category.UID];
            }
            
            DOMNewlyPopulatedElements["category-"+category.UID].appendChild(this.getOrCreateDOMListElement(result.title, result.date, result.time, result.permalink));
        }
    }
    
    for(categoryId in this.DOMPopulatedElements)
    {
        this.DOMPopulatedElements[categoryId].innerHTML= "";
        this.DOMPopulatedElements[categoryId].appendChild(this.getOrCreateDOMListElement("No Results", "", ""));
    }
    
    this.DOMListElements.count= 0;
    this.DOMPopulatedElements= DOMNewlyPopulatedElements;
}

window.addEventListener("load", function() { window.blogSearch= new FTBlogSearch(); }, false);