function get_qs() {
    var q = document.URL;
    var i = q.indexOf('?');
    if (i < 0) return null;
    var f = q.indexOf('#');
    return q.substring(i+1, f == -1 ? q.length : f - 1);
}

var opts = { page: 1, num: 10 };

function parse_query() {
    var qs = get_qs();
    if (!qs) return;
    var pairs = qs.split('&');
    for (var i=0; i < pairs.length; i++) {
        p = pairs[i].split('=');
        opts[p[0]] = p[1];
    }
    var es = [];
    for (var i=0; i < engines.length; i++) {
        if (engines[i] in opts) es.push(engines[i]);
    }
    opts.engines = es.length ? es : engines;
    query();
}

function request_obj() {
    if (window.XMLHttpRequest) {
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        return new ActiveXObject('Microsoft.XMLHTTP');
    }
}

function json_request(u, m, o, f) {
    var r = request_obj();
    r.open(m, u, true);
    r.onreadystatechange = function () {
        if (r.readyState == 4) f(r, eval('('+r.responseText+')'));
    };
    if (m == 'POST' || m == 'PUT') {
        r.setRequestHeader('content-type','text/plain');
        r.send(o.toJSONString());
    } else {
        r.send(null);
    }
}

function query() {
    for (var i=0; i < opts.engines.length; i++) {
        add_engine(opts.engines[i]);
    }
}

function add_engine(e) {
    json_request('/rest_query/'+e+'?'+opts.query,'GET',null,add_results(e));
}

function remove_engine(e) {
    results.update(e, null);
}

function add_results(e) {
    return function (r,o) { if (r.status == 200) results.update(e, o); };
}

function set_num(n) {
    opts.num = n;
    opts.page = 1;
    results.display();
}

function next_page() {
    opts.page++;
    results.display();
}

function prev_page() {
    if (opts.page == 1) return;
    opts.page--;
    results.display();
}

function go_page(p) {
    opts.page = p;
    results.display();
}

function sort_by(sort) {
    opts.sort = sort;
    opts.page = 1;
    results.display();
}

function $x(p,t){
    for(var i in t)
        typeof(t[i])=='object'
            ?$x(p.appendChild(document.createElement(i.split('_')[0])),t[i])
        :i=='s'
            ?p.style.cssText=t[i]
        :i.split('_')[0]=='t'
            ?p.appendChild(document.createTextNode(t[i]))
        :p[i]=t[i];
    return p;
}

function format_result(n, r) {
    var t = document.createElement('table');
    t.setAttribute('class','result');
    t.setAttribute('cellpadding','0');
    t.setAttribute('cellspacing','0');
    t.setAttribute('border','0');
    t.setAttribute('id','result_'+n);
    var el = '';
    var ei;
    for (var i=0; i < r.engine_index.length; i++) {
        ei = r.engine_index[i];
        el += '<a href="'+engine_links[ei[0]]+'">'+ei[0]+'('+ei[1]+')</a> ';
    }
    $x(t, {
        tbody:{tr:{
            td:{align:'left',valign:'top',innerHTML:embed_flash(n, r.url)},
            td_1:{align:'right',valign:'top',s:'padding:10px 4px;',
                span:{className:'result_number',t:n+'.'}},
            td_2:{align:'left',valign:'top',width:'100%',s:'padding:10px 20px 10px 0;',
                span:{className:'result_title',a:{href:r.url,innerHTML:r.title}},br:{},
                span_1:{className:'result_url',t:r.url},br_1:{},
                span_2:{className:'result_desc',innerHTML:'Description: '+r.desc},br_2:{},
                span_3:{className:'result_links',a:{href:'#',t:'Kaxy index: '+r.kaxy_index},
                span:{innerHTML:' ( '+el+' ) | '},a_1:{href:r.url,target:'_blank',t:'New Window'},
                t_1:' | ',a_2:{href:'https://webproxy.kaxy.com/b/'+b64encode(r.url),t:'Browse Anonymously'},
                t_2:' | ',a_3:{href:'javascript:kaxy_spam_kill('+n+');',t:'Report this site as Spam!'}}}
        }}
    });
    return t;
}

function by_kaxy_index(a, b) { return a.kaxy_index - b.kaxy_index; }

function cmp(a, b) {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

function by_title(a, b) { return cmp(a.title, b.title); }

function by_source(a, b) { return cmp(a.url, b.url); }

String.prototype.startswith = function (s) {
    return (this.substr(0, s.length) == s);
}

Array.prototype.contains = function (o) {
    for (var i=0; i < this.length; i++) {
        if (this[i] === o) return true;
    }
    return false;
}

function page_links(nr) {
    var pages = Math.ceil(nr / opts.num);
    var d = document.createElement('span');
    var a;
    if (opts.page > 1) {
        a = document.createElement('a');
        a.setAttribute('onclick','prev_page();');
        a.setAttribute('href','#');
        a.setAttribute('class','grey');
        a.innerHTML = '&lt;&nbsp;';
        d.appendChild(a);
    }
    for (var i=1; i <= pages; i++) {
        a = document.createElement('a');
        a.setAttribute('onclick','go_page('+i+');');
        a.setAttribute('href','#');
        if (i == opts.page) {
            a.setAttribute('class','selected');
        } else {
            a.setAttribute('class','grey');
        }
        a.innerHTML = i;
        d.appendChild(a);
        d.innerHTML += '&nbsp;';
    }
    if (opts.page < pages) {
        a = document.createElement('a');
        a.setAttribute('onclick','next_page();');
        a.setAttribute('href','#');
        a.setAttribute('class','grey');
        a.innerHTML = '&gt;';
        d.appendChild(a);
    }
    return d;
}

var results = {
    urls: [],
    engines: {},
    ne: 0,
    
    update: function(e, rs) {
        if (rs == null) {
            if (e in this.engines) {
                this.ne--;
                delete this.engines[e];
                var urls = [];
                for (var i=0; i < this.urls.length; i++) {
                    for (var j=0; j < engines.length; j++) {
                        if (engines[j] in this.engines &&
                            this.urls[i] in this.engines[engines[j]]) {
                                urls.push(this.urls[i]);
                                break;
                        }
                    }
                }
                this.urls = urls;
            }
        } else {
            if (!(e in this.engines)) this.ne++;
            this.engines[e] = {results: rs.length};
            var offset = rs.length / 2;
            var url;
            for (var i=0; i < rs.length; i++) {
                r = rs[i];
                r.index = i + 1;
                r.weight = weights[e].result * (i - offset);
                if (!this.urls.contains(r.url)) this.urls.push(r.url);
                this.engines[e][r.url] = r;
            }
        }
        delete this.cached_results;
        this.display();
    },
    
    weighted_results: function() {
        if ('cached_results' in this) return this.cached_results;
        var results = [];
        var url, result, e, er;
        for (var i=0; i < this.urls.length; i++) {
            url = this.urls[i];
            result = {engine_index: [], kaxy_index: 0.0, url: url};
            for (var j=0; j < engines.length; j++) {
                e = engines[j];
                if (e in this.engines) {
                    if (!(url in this.engines[e])) continue;
                    er = this.engines[e][url];
                    result.engine_index.push([e, er.index]);
                    result.kaxy_index += er.weight;
                    if (!('title' in result) || (weights[e].title > result.title[0])) {
                        result.title = [weights[e].title, er.title];
                    }
                    if (!('desc' in result) || (weights[e].desc > result.desc[0])) {
                        result.desc = [weights[e].desc, er.desc];
                    }
                }
            }
            result.title = result.title[1];
            result.desc = result.desc[1];
            result.kaxy_index /= this.ne;
            results.push(result);
        }
        this.cached_results = results;
        return results;
    },
    
    display: function() {
        var results = this.weighted_results();
        switch (opts.sort) {
            case 'source':
                results.sort(by_source);
                break;
            case 'title':
                results.sort(by_title);
                break;
            default:
                results.sort(by_kaxy_index);
        }
        var num = Number(opts.num);
        var page = Number(opts.page);
        var first = num * (page - 1);
        var last = Math.min(first+num, results.length);
        var container = document.getElementById('result_container');
        container.innerHTML = '<table border="0" cellpadding="5" cellspacing="5" width=""><tr><td align="center" valign="middle">Searching with: '+opts.engines.join(' ')+'<br>Showing results '+(first+1)+' to '+(last+1)+' of '+results.length+' for: '+opts.query+'</td></tr></table>';
        for (var i=first; i < last; i++) {
            container.appendChild(format_result(i+1, results[i]));
        }
        var tb = document.getElementById('toolbar_bottom');
        while (tb.firstChild) tb.removeChild(tb.firstChild);
        tb.appendChild(page_links(results.length));
    }
}

var engines = ['google','ask','gigablast','dmoz','looksmart','yahoo','msn','overture'];

var engine_links = {
    google:'http://www.google.com/',
    ask:'http://web.ask.com/',
    gigablast:'http://www.gigablast.com/',
    dmoz:'http://search.dmoz.org/',
    yahoo:'http://search.yahoo.com/',
    msn:'http://search.msn.com/',
    exalead:'http://www.exalead.com/'
}

var weights = {
    google:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    ask:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    gigablast:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    dmoz:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    yahoo:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    msn:{
        result:1.0,
        title:1.0,
        desc:1.0
    },
    exalead:{
        result:1.0,
        title:1.0,
        desc:1.0
    }
}

function preview_url() {
    var n = 1;
    return function(url) {
        if (n == 1) { n = 2; } else { n = 1; }
        return 'http://preview'+n+'.kaxy.com/p/'+b64encode(url)+'.jpg';
    };
}
preview_url = preview_url();

function stw_preview_url(url) {
    return 'http://new.kaxy.com/tmb/' + b64encode(url) + '.jpg';
	//return 'http://www.shrinktheweb.com/xino.php?&embed=1&STWAccessKeyId=5507ded3193be53&Size=sm&stwUrl=' + url;
}

var detected_proper_flash = DetectFlashVer(8,0,0);

function embed_flash(n, url) {
    if (detected_proper_flash) {
        return AC_FL_RunContent(
            "src", "http://new.kaxy.com/_images/_results/thumbnail",
            "width", "110",
            "height", "110",
            "align", "middle",
            "quality", "high",
            "bgcolor", "#FFFFFF",
            "id", "swf_"+n,
            "name", "swf_"+n,
            "allowScriptAccess","always",
            "type", "application/x-shockwave-flash",
            "codebase", "http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab",
            "pluginspage", "http://www.adobe.com/go/getflashplayer",
            "FlashVars","the_id="+n+"&thumbnailURL="+stw_preview_url(url)
        );
    } else {
        return '<img src="'+stw_preview_url(url)+'" width="100" height="100" onMouseOver="this.width=200;this.height=200;" onMouseOut="this.width=100;this.height=100;" style="border:1px solid #000; margin:5px;" />';
    }
}
