/*!
*	Copyright (c) 2007 Bethke et al. GmbH, Berlin, Germany copyright@b-et-a.de
* All rights reserved.
* Author: Ingo Struck - seen at ingostruck dot de
*/
var channel = {
	the_dom : false
	,my_dom : false
	,chn : {}
	,qhead : {}
	,qtail : {}

	// return: [my_dom,the_dom,port:]
	,url2dom : function ( url ) {
		if (!url) return false;
		var ret = [false,false,false];
		var dom = url;
		var port = '';
		var s = dom.indexOf('://');
		if ( 0 <= s ) dom = dom.substring(s+3);
		var e = dom.indexOf('/');
		if ( 0 <= e ) dom = dom.substring(0,e);
		e = dom.indexOf(':');
		if ( 0 <= e ){
			port = dom.substring(e); // including ':'
			dom = dom.substring(0,e);
		}
		ret[0] = dom;
		e = dom.lastIndexOf('.'); //skip tld
		if ( '.uk' == dom.substring(e) ) { e = dom.lastIndexOf('.',e-1); } // .co.uk
		e = dom.lastIndexOf('.',e-1);
		if ( 0 <= e ) dom = dom.substring(e+1);
		if ('spiegel.de' == dom) dom = 'seen.by.spiegel.de';
		ret[1] = dom;
		ret[2] = port;
		return ret;
	}

	,_XHR : function () {
		try { return new ActiveXObject("MSXML3.XMLHTTP"); } catch (e) {}
		try { return new ActiveXObject("MSXML2.XMLHTTP.3.0"); } catch (e) {}
		try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
		try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
		try { return new XMLHttpRequest(); } catch (e) {}
		return false;
	}

	,_csend : function (win, url, meth, cbn, data) {
		var rq = win.channel._XHR();
		if (!rq) return false;
		if (!meth) meth = 'GET';
		meth = meth.toUpperCase();
		
		if ( data && 'GET' == meth ) {
			url += (-1 < url.indexOf("?") ? "&" : "?") + encodeURIComponent(data);
			data = null;
		}
		rq.open(meth, url);

		if (cbn) {
			rq.onreadystatechange = function() {
				if (4 == rq.readyState) {
					if ( 'function' == typeof(cbn) ) {
						cbn(rq.responseText, rq.status, rq.getAllResponseHeaders());
					} else {
						var path = cbn.split('.');
						var cb = win[path[0]];
						for (var i = 1; cb && i < path.length; ++i)
							cb = cb[path[i]];
						cb(rq.responseText, rq.status, rq.getAllResponseHeaders());
					}
					rq.onreadystatechange = function () {};
				}
			}
		}
		rq.send(data);
	}

	,_make : function (dom, chname) {
		if (!document.createElement || !document.domain) return false;
		var cURL = 'http://'+dom+'.'+document.domain;
		cURL += '/channel';
		var chn = false;
		var body = document.body;
		try {
			var t=document.createElement('iframe');
			t.id=chname;
			t.src=cURL;
			t.style.border='0px';
			t.style.width='0px';
			t.style.height='0px';
			chn = body.appendChild(t);

			if (document.frames) {
				// this is for IE5 Mac, because it will only
				// allow access to the document object
				// of the IFrame if we access it through
				// the document.frames array
				chn = document.frames[chname];
			}
		} catch(exception) {
			alert('channel._make IE5 PC');
			// This is for IE5 PC, which does not allow dynamic creation
			// and manipulation of an iframe object. Instead, we'll fake
			// it up by creating our own objects.
			iframeHTML='\<iframe id="'+chname+'" src="'+cURL+'" style="';
			iframeHTML+='border:0px;';
			iframeHTML+='width:0px;';
			iframeHTML+='height:0px;';
			iframeHTML+='"><\/iframe>';
			document.body.innerHTML+=iframeHTML;
			chn = new Object();
			chn.document = new Object();
			chn.document.location = new Object();
			chn.document.location.iframe = document.getElementById(chname);
			chn.document.location.replace = function(location) {
				this.iframe.src = location;
			}
		}

		channel.chn[chname] = chn;
		return chn;
	}

	,_q : function (name, url, meth, cbn, data) {
		var entry = [url, meth, cbn, data, null];
		var tail = channel.qtail[name];
		if (null != tail) {
			if ('_qdone_'==tail) return;
			tail[4] = entry;
			channel.qtail[name] = entry;
		} else {
			channel.qhead[name] = entry;
			channel.qtail[name] = entry;
		}
	}

	,dqueue : function (name, win) {
		var entry = channel.qhead[name];
		while (null != entry) {
			var next = entry[4];
			channel.qhead[name] = next;
			win.channel._csend(win, entry[0], entry[1], entry[2], entry[3]);
			entry = next;
		}
		channel.qtail[name] = '_qdone_';
	}

	,send : function (dom, uri, meth, cb, data) {
		if (!document.domain) return;
		var udom;
		if (dom) udom = dom + '.' + document.domain; else udom = channel.my_dom;
		var url = 'http://' + udom + uri;
		// direct sending if my_dom == dom || the_dom == dom; if it fails, use chn_send all the way
		if (channel.my_dom == udom) {
			try {
				channel._csend(window, url, meth, cb, data);
				return;
			} catch (e) {
			}
		}
		
		var name = 'chn_' + dom;
		var chn = channel.chn[name];
		if (!chn) chn = channel._make(dom, name);
		
		if ('_qdone_'!=channel.qtail[name]) {
			channel._q(name, url, meth, cb, data);
		} else {
			var win = document.all ? document.frames[name] : document.getElementById(name).contentWindow;
			win.channel._csend(win, url, meth, cb, data);
		}
	}

	,fetch : function (ucn, uri, cb) {
		send(ucn, uri,'GET',cb);
	}

	,onReady : function () {
		var dom = channel.url2dom(document.URL);
		channel.my_dom = dom[0];
		channel.the_dom = dom[1];
		document.domain = channel.the_dom;
	}
};
