// Copyright Inipix AB 2005. All rights reserved.
// Please respect the copyright and do not use Ctrl-C Ctrl-V.

function writeLayer(id, txt){
	if (document.getElementById){
		document.getElementById(id).innerHTML=txt;
	} else if(document.all){
		document.all[id].innerHTML=txt;
	} else if(document.layers){
		with(document.layers[id].document){
			open();
			write(txt);
			close();
		}
	}
}

function getId(id) {
	var it = false;
	if (document.getElementById) {
		it = document.getElementById(id);
	} else if (document.all) {
		it = document.all[id];
	} else if (document.layers) {
		it = document.layers[id];
	}
	
	return it;
}

function show(id) {
	z = getId(id);
	z.style.display = "";
	z.style.visibility = "visible";
}

function hide(id) {
	z = getId(id);
	z.style.display = "none";
	// z.style.visibility = "invisible"; ?
}


function smartMath(t) {
	if (t.match('[+-/]') || t.match('\\*')) {
		try {
			answer = eval(t);
			if (answer != "undefined" && answer != "Infinity") {
				writeLayer("smart", "Is the answer <b>" + answer + "</b> perhaps?");
				show("helper");
			}
		} catch (er) {
			hide("helper");
		}
	}
}


function Decider() {
	this.r = d_reg;
	this.hit = d_hit;
	this.inp = d_inp;
	this.enter = d_enter;
	this.key = d_key;
	this.hili = d_hili;
	this.resrender = d_resrender;
	this.insresafter = d_insresafter;
	
	this.sel = -1;
	this.allow = true;
	this.tx = "";
	
	this.mx = new Array();
	this.res = new Array();
}

function d_reg(func, regx) {
	this.mx.push(new Matcher(this, func, regx));
}

function d_hit(reso, regex) {
	reso.rx(regex);
	this.res.push(reso);
}

function d_inp(elm) {
	if (this.allow) {
		var tx = elm.value;
		this.tx = tx;
		
		if (tx == "") {
			hide("sres");
			show("nosres");
		} else {
			show("sres");
			hide("nosres");
			
			while (runningAjax.length > 0) {
				rq = runningAjax.shift();
				rq.onTimeoutInternal();
			}

			this.res = new Array();
			for (i = 0; i < this.mx.length; i++) {
				this.mx[i].check(tx);
			}
		
			this.resrender();
		
			hide("helper");
			writeLayer("smart", "");
			smartMath(tx);
		}
	}
}

function d_resrender() {
	var tell = "";
	
	for (i = 0; i < this.res.length; i++) {
		var url = this.res[i].url;
		var desc = this.res[i].desc;
		var query = this.res[i].query;
		
		if (desc == "") {
			desc = "Search <b>" + this.res[i].exname(url) + "</b> for " + query;
		} else {
			desc = "<b>" + desc + "</b>";
		}
			
		if (this.res[i].rss > 0) {
			if (this.res[i].active == true) {
				desc = '<img src="active.gif" hspace="2"/>' + " Retrieving feed from <b>" + this.res[i].exname(url) + "</b> on " + query;
			} else {
				desc = "From " + this.res[i].exname(this.res[i].srcurl) + ": <b>" + desc + "</b>";
				if (this.res[i].rss == 1) desc = '<img src="feed.png" hspace="2"/>' + desc;
				if (this.res[i].rss == 2) desc = '<img src="feed-sub.gif" hspace="2"/>' + desc;
			}
		}
		
		
		tell = tell + "<div id=\"res" + i + "\" class=\"nomark\">" + desc + ".<br></div>";
	}
	
	writeLayer("tell", tell);

	if (this.res.length > 0) {
		if (this.sel >= this.res.length || this.sel < 0) this.sel = 0;
		this.hili(dec.sel);
	} else {
		this.sel = -1;
	}
}

function d_enter() {
	if (this.sel >= 0 && this.sel <= this.res.length) {
		var u = this.res[this.sel].url;
		
		if (document.images) { 
			(new Image()).src="learn.php?q=" + this.tx + "&sel=" + escape(this.sel) + "&url="+escape(u).replace(/\+/g,"%2B") + "&rx="+escape(this.res[this.sel].regex).replace(/\+/g,"%2B");
		}

		window.location = u;
		return false;
	}
	
	writeLayer("tell", "Nowhere to go!");
	return false;
}

function d_key(event) { // this != dec
	dec.allow = true;

	if (event.keyCode == 40) {	//KEY DOWN
		dec.sel++;
		if (dec.sel >= dec.res.length) dec.sel = 0;
		dec.hili(dec.sel);
		dec.allow = false;
	} else if (event.keyCode == 38 ) { //KEY UP
		dec.sel--;
		if (dec.sel < 0) dec.sel = dec.res.length - 1;
		dec.hili(dec.sel);
		dec.allow = false;
	} 
}

function d_hili(ix) {
	for (i = 0; i < dec.res.length; i++) {
		hili = document.getElementById("res" + i);
		if (i == ix) {
			hili = hili.className = "mark";
		} else {
			hili = hili.className = "nomark";
		}
	}
}

function d_insresafter(after, resobj) {
	addHere = 0;
	
	for (i = 0; i < this.res.length; i++) {
		if (this.res[i].url == after.url) addHere = i;
		alert(addHere + "\n" + after.url + "\n" + this.res[i].url);
	}
	
	this.res.splice(addHere + 1, 0, resobj);
	
	return resobj;
}


function Matcher(boss, func, regx) {
	this.check = m_check;

	this.callback = boss;
	this.rx = regx;
	this.func = func;
}

function m_check(t) {
	if (t.match(this.rx)) this.callback.hit(this.func(RegExp.$1), this.rx);
}


function Res(url, desc, query) {
	this.exname = r_exname;
	this.rx = r_rx;
	
	this.url = url;
	this.desc = desc;
	this.query = query;
	this.srcurl = url;
	this.active = false;
	this.rss = 0;
	
	this.regex = "";
}

function r_exname(st) {
	st.match("http://(.*)\\..*?/");
	RegExp.$1.match("\\.([A-Za-z0-9]*)");
	return RegExp.$1.replace(/^(.)/mg, function(x) {return x.toUpperCase()});
}

function r_rx(reg) {
	this.regex = reg;
}



function Cache() {
	this.cache = new Array();
	
	this.get = rc_get;
	this.put = rc_put;
}

function rc_get(url) {
	return this.cache[url];
}

function rc_put(url, data) {
	this.cache[url] = data;
}

var cacheRss = new Cache();
var cacheRssObjs = new Cache();
var runningAjax = new Array();



function LiveRss(src, q) {
	this.src = src;
	this.res = new Res(src, "", q);
	this.res.rss = 1;
	this.res.srcurl = src;

	cacheRssObjs.put(src, this);
	
	this.run = lr_run;
	this.reply = lr_reply;
	this.handle = lr_handle;
}

function lr_run() {
	cached = cacheRss.get(this.src);
	
	if (typeof(cached) == "undefined") {
		rq = AjaxRequest.post({
			'url': "proxy.php",
			'onSuccess':this.reply,
			'parameters':{ 'url': this.src }
		});
		
		this.res.active = true;
		runningAjax.push(rq);
	} else {
		this.handle(cached);
	}
	
	return this.res;
}

// Fake func, will not be in "this" instance context, emulate with obj cache!
function lr_reply(req) {
	cacheRss.put(req.parameters['url'], req.responseText);

	me = cacheRssObjs.get(req.parameters['url']);
	me.handle(req.responseText);
	me.res.active = false;
	dec.resrender(); // will recurse if called in handle!
}

function lr_handle(json) {
	eval(json);

	if (dataObj.results.length > 0) {
		this.res.desc = dataObj.results[0].title;
		this.res.url = dataObj.results[0].link;

		if (dataObj.results.length > 1)  {
			pt = new Res(dataObj.results[1].link, dataObj.results[1].title, "");
			pt.rss = 2;

			// Detta strular pga att "huvudresultatet" inte lagts till ännu i res, utan returneras från lr_run. Därför konstig ordning på res osv!
			// Använd någon av dessa funktioner, push är säkrast ännu så länge, insresafter kan recursera
			//pt = dec.insresafter(this.res, pt);
			//pt = dec.res.push(pt);
		}

	}
}




function funcname(f) {
 var s = f.toString().match(/function (\w*)/)[1];
 if ((s == null) || (s.length==0)) return "anonymous";
 return s;
}
function stacktrace() {
 var s = "";
 for (var a = arguments.caller; a !=null; a = a.caller) {
   s += "->"+funcname(a.callee) + "\n";
   if (a.caller == a) {s+="*"; break;}
 }
 return s;
}



var dec = new Decider();

if (document.attachEvent) {
	var ok = document.attachEvent("onkeydown", dec.key);
} else {
	document.onkeydown = dec.key;
}


