/*
ContextualTracker
http://ContextualTracker.wiadomosc.info/

Copyright (C) 2006 Tobiasz 'gosciu' Cudnik
gosc@wiadomosc.info

You can use ContextualTracker free of charge.
Distribution and code reuse NOT permitted.
*/

var ct_location = self.location;
var ct_statusWorking = false;
var ct_status = '';

var _ct_trackedFrames = Array();
var _ct_URLClickHandlers = Array();
var _ct_funcClickHandlers = Array();
var _ct_focusLastClick = '';
var _ct_clicks = new Array();
var _ct_onFrame = null;
var _ct_blurs = 0;
var _ct_onFrameStatic = null;

// test window.status avability
window.status = 'test';
if ( window.status == 'test' ) {
	ct_statusWorking = true;
	window.status = '';
}

function ct_trackFrame( obj, callbackFunc, vars )
{
	var idx = _ct_trackedFrames.length;
	_ct_trackedFrames[idx] = new Array();

	_ct_trackedFrames[idx]['frame'] = obj;
	_ct_trackedFrames[idx]['callback'] = callbackFunc;
	_ct_trackedFrames[idx]['mouseover'] = false;
	_ct_trackedFrames[idx]['clicked'] = 0;

	if ( vars != null )
		_ct_trackedFrames[idx]['vars'] = vars;

	if ( ct_isIE() ) {
		if ( idx == 0 )		// register only once
			window.attachEvent('onbeforeunload', _ct_runClickHandlers);

		obj.attachEvent('onfocus', _ct_trackFrameFocus);
		obj.attachEvent('onblur', _ct_trackFrameBlur);
		obj.attachEvent('onmouseover', _ct_trackFrameMouse);
		obj.attachEvent('onmouseout', _ct_trackFrameMouse);

		ct_debug("tracking frame '"+obj.name+"'; IE", 2);
	}
	else if ( ct_isOpera() ) {
		if ( idx == 0 ) {	// register only once
			window.addEventListener('blur', _ct_trackCheck, false);
			window.addEventListener('mouseover', _ct_trackFrameMouseReverse, false);
			window.addEventListener('mouseout', _ct_trackFrameMouseReverse, false);
			window.addEventListener('unload', _ct_runClickHandlers, false);
		}

		ct_debug("tracking frame '"+obj.name+"'; Opera", 2);
	}
	else {
		if ( idx == 0 )	{	// register only once
	//		window.addEventListener('unload', ct_dumpEvent, false);
	//		window.addEventListener('beforeunload', ct_debugDump, false);
	//		window.addEventListener('beforeunload', new Function('e','ct_debug( e.target.tagName+" "+e.target.name )'), false);
	//		window.addEventListener('pagehide', ct_dumpEvent, false);
	//		window.addEventListener('focus', ct_dumpEvent, false);

	//		window.addEventListener('blur', _ct_trackCheck, false);
			window.addEventListener('beforeunload', _ct_trackStatic, false);
			window.addEventListener('unload', _ct_trackCheckW3C, false);
			window.addEventListener('unload', _ct_runClickHandlers, false);
		}

		obj.addEventListener('mouseover', _ct_trackFrameMouse, false);
		obj.addEventListener('mouseout', _ct_trackFrameMouse, false);

		ct_debug("tracking frame '"+obj.name+"'; Gecko / W3C", 2);
	}
}

function ct_storeClick( data )
{
	ct_debug('+++ click stored');
	_ct_clicks.push( data );
}

function _ct_unstoreClick()
{
	ct_debug('--- click unstored');
	_ct_clicks.pop();
}

// registers URL handler (a GET request)
// using varNames you can change arg names, eg varNames['channel'] == 'ch' changes arg &channel= to &ch= in URI
// null values in varNames turns off specifed arg
function ct_registerURLClickHandler( url, varNames )
{
	var idx = _ct_URLClickHandlers.length;
	_ct_URLClickHandlers[idx] = new Array();

	_ct_URLClickHandlers[idx]['url'] = url;
	_ct_URLClickHandlers[idx]['vars'] = varNames || new Object();

	return idx+1;
}

function ct_registerFuncClickHandler( handler )
{
	_ct_funcClickHandlers.push( handler );
	return _ct_funcClickHandlers.length;
}

function _ct_runClickHandlers()
{
	ct_debug('running handlers');
	// loop through all stored clicks
	for (var c=0; c<_ct_clicks.length; c++ ) {
		// run URL handlers first...
		for ( var i=0; i < _ct_URLClickHandlers.length; i++ ) {
			var url = '';

			for ( key in _ct_clicks[c] ) {
				// skip unwanted args
				if (! _ct_URLClickHandlers[i]['vars'][ key ] && typeof _ct_URLClickHandlers[i]['vars'][ key ] != 'undefined' )	// skip arg
					continue;

				// replace arg name ?
				var arg = '';
				if ( _ct_URLClickHandlers[i]['vars'][ key ] )
					arg = _ct_URLClickHandlers[i]['vars'][ key ];
				else
					arg = key;

				if ( typeof encodeURIComponent == 'function' )
					url += '&'+arg+'='+encodeURIComponent( _ct_clicks[c][ key ] );
				else
					url += '&'+arg+'='+escape( _ct_clicks[c][ key ] );
			}

			ct_sendData( _ct_URLClickHandlers[i]['url']+url );
		}

		// and now function handlers...
		for ( var i=0; i < _ct_funcClickHandlers.length; i++ ) {
			var url = '';
			eval ( _ct_funcClickHandlers+"( _ct_clicks[c] )" );
		}
	}
	ct_debug('all finished, getting out...', 2);
}

function ct_cancelClick( frameObj )
{
	var idx = ct_findFrame( frameObj );

	if ( idx < 0 )
		return false;

	_ct_trackedFrames[idx]['clicked']--;
	return true;
}

function ct_findFrame( frameObj )
{
	for ( var i=0; i < _ct_trackedFrames.length; i++ ) {
		if ( frameObj == _ct_trackedFrames[i]['frame'] )
			return i;
	}

	return -1;
}

function ct_sendData( url )
{
	ct_debug('sending data...');

	// avoid caching
	url += url.indexOf('?') == -1 ? '?time='+(new Date()).getTime(): '&time='+(new Date()).getTime();
	ct_debug( url, 3 );

	if ( ct_cfgGet('ajax') ) {
		var ajax = getAJAX();
		if ( ajax ) {
			ct_debug('using ajax', 2);

	//		ajax.onreadystatechange = _ct_get_id;
			ajax.open('HEAD', url, false);	// no async, wait for response
			ajax.send('');
			return true;
		}
	}

	ct_debug('using script append', 2);

	var head = document.getElementsByTagName("head")[0];
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.src = url;
	head.appendChild(script);
	ct_wait(500);
}

// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
function ct_wait(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
			return;
	}
}

function ct_cfgGet( name )
{
	if ( typeof ct_cfg == 'undefined' ) return false;
	if ( typeof ct_cfg[ name ] == 'undefined' ) return false;
	return ct_cfg[ name ];
}

/*function _ct_get_id()
{
	if ( _ct_ajax.readyState == 4 ) {
		if ( _ct_ajax.status == 200 ) {
			_ct_last_click_id = _ct_ajax.responseText;
        }
		else {
			ct_debug('bad tracker http response');
		}
	}
}*/

// TRACKING STUFF (priv)

function _ct_trackStatic( event )
{
	if ( _ct_onFrame === null ) {
		ct_debug('no mouseover any frame...', 3);
		return;
	}

	if ( event.type == 'beforeunload' && ct_isW3C() && event.target.tagName ) {
		ct_debug('firefox, fake beforeunload', 3);
		return;
	}

	_ct_onFrameStatic = _ct_onFrame;
	ct_debug('saved static mouseover for frame '+_ct_onFrameStatic, 3);
}

function _ct_trackCheckW3C( event, staticOnly )
{
	if ( _ct_onFrameStatic === null ) {
		ct_debug('no mouseover any frame...', 3);
		return;
	}

	if ( _ct_trackedFrames[ _ct_onFrameStatic ]['clicked'] ) {
		ct_debug('frame already clicked...', 2);
		return;
	}

	if ( event.type == 'blur' && ! ct_isOpera() ) {
		_ct_blurs++;

		if ( _ct_blurs%2 == 1 ) {
			ct_debug('firefox, skipping first blur: '+_ct_blurs, 3);
			return;
		}
	}

	if ( event.type == 'beforeunload' && ct_isW3C() && event.target.tagName ) {
		ct_debug('firefox, fake beforeunload', 3);
		return;
	}

	ct_status = window.status;
	ct_debug("click !");
	_ct_trackedFrames[ _ct_onFrameStatic ]['clicked']++;
	_ct_trackRunCallback( _ct_onFrameStatic );
}

function _ct_trackCheck( event, staticOnly )
{
	if ( _ct_onFrame === null ) {
		ct_debug('no mouseover any frame...', 3);
		return;
	}

	if ( _ct_trackedFrames[ _ct_onFrame ]['clicked'] ) {
		ct_debug('frame already clicked...', 2);
		return;
	}

	ct_status = window.status;
	ct_debug("click !");
	_ct_trackedFrames[ _ct_onFrame ]['clicked']++;
	_ct_trackRunCallback( _ct_onFrame );
}

function _ct_trackFrameFocus( e )
{
	var idx = ct_findFrame( e.target || e.srcElement );

	if ( idx == -1 )
		return;

	ct_debug('focus', 3);

	if ( _ct_mouseOver( _ct_trackedFrames[idx]['frame'], e ) ) {
		ct_debug('focus IN FRAME', 2);
		ct_status = window.status;
		ct_debug("click !");
		_ct_trackedFrames[ idx ]['clicked']++;

		_ct_focusLastClick = 'focus';
		_ct_trackRunCallback( idx );
	}
}

function _ct_trackFrameBlur( e )
{
	ct_debug('blured focus', 3);

	if ( _ct_focusLastClick == 'focus' )
		_ct_unstoreClick();

	if ( _ct_onFrame === null ) {
		ct_debug('no mouseover any frame...', 3);
		return;
	}

	ct_debug('blured focus IN FRAME', 2);
	ct_debug("click !");

	ct_status = window.status;

	_ct_trackedFrames[ _ct_onFrame ]['clicked']++;
	
	if ( ct_cfgGet('autohide') ) {
		ct_debug('hidding frame', 2);
		_ct_trackedFrames[ _ct_onFrame ]['frame'].style.visibility = 'hidden';
	}

	_ct_focusLastClick = 'blur';
	_ct_trackRunCallback( _ct_onFrame );
}

function _ct_mouseOver( obj, e )
{
	var mouse = ct_getMouse( e );
	var frameLeft = ct_findX( obj );
	var frameTop = ct_findY( obj );

	var inX = (mouse.x >= frameLeft && mouse.x <= ( frameLeft + parseInt(obj.width) ) );
	var inY = (mouse.y >= frameTop && mouse.y <= ( frameTop + parseInt(obj.height) ) );

	return inX && inY;
}

function _ct_trackRunCallback( idx )
{
	ct_debug('running callback', 3);
	if ( typeof _ct_trackedFrames[idx]['vars'] != 'undefined' )
		eval( _ct_trackedFrames[idx]['callback']+"( _ct_trackedFrames["+idx+"]['frame'], _ct_trackedFrames["+idx+"]['vars'] )" );
	else
		eval( _ct_trackedFrames[idx]['callback']+"( _ct_trackedFrames["+idx+"]['frame'] )" );
}

function _ct_trackFrameMouse( e )
{
	var idx = ct_findFrame( e.target || e.srcElement );

	if ( idx == -1 )
		return;

	if ( e.type == 'mouseover' ) {
		_ct_trackedFrames[idx]['mouseover'] = true;
		_ct_onFrame = idx;
		ct_debug('over frame '+idx, 3);
	}
	else {
		_ct_trackedFrames[idx]['mouseover'] = false;
		if ( _ct_onFrame === idx ) _ct_onFrame = null;
		ct_debug('out of frame '+idx, 3);
	}
}

function _ct_trackFrameMouseReverse( e )
{
	if ( e.type == 'mouseover' ) {		// mouse over the window means no mouse over any frame
		for ( var i=0; i < _ct_trackedFrames.length; i++ ) {
			_ct_trackedFrames[i]['mouseover'] = false;
			if ( _ct_onFrame === i ) {
				_ct_onFrame = null;
				ct_debug('out of frame '+i, 3);
			}
		}
	}
	else {
		for ( var i=0; i < _ct_trackedFrames.length; i++ ) {
			if ( _ct_mouseOver( _ct_trackedFrames[i]['frame'], e ) ) {
				_ct_trackedFrames[i]['mouseover'] = true;
				_ct_onFrame = i;
				ct_debug('over frame '+i, 3);
				break;
			}
		}
	}
}

// USEFULL STUFF

function ct_dumpEvent( e )
{
	ct_debug('EVENT: '+e.type+'; '+e.tagName+' '+( e.taget || e.srcElement ));
}

function ct_debugDump( obj )
{
	ct_debug( ct_dump( obj ) );
}

function ct_dump( obj )
{
	var txt = '';
	for( var i in obj ) {
		txt += i+' = '+obj[i]+"\n";
	}
	return txt;
}

function ct_debug( input, level )
{
	if ( typeof level == 'undefined' ) level = 1;
	if ( ct_cfgGet('debug') < level ) return;

	if (! ct_cfgGet('debug_obj_redir') ) {
		alert( 'DEBUG: '+input );
		return;
	}

	var db = document.getElementById( ct_cfgGet('debug_obj_redir') );
	if (! db ) return;
	tmp = document.createElement('div');
	tmp.innerHTML = input;
	db.appendChild( tmp );

	if ( window.clipboardData ) 
		window.clipboardData.setData('Text', db.innerHTML);
}

function ct_getMouse(e)
{
	var pos = {x:0, y:0};

	if (e.pageX || e.pageY)
	{
		pos['x'] = e.pageX;
		pos['y'] = e.pageY;
	}
	else if (e.clientX || e.clientY)
	{
		pos['x'] = e.clientX + document.body.scrollLeft;
		pos['y'] = e.clientY + document.body.scrollTop;
	}

	return pos;
}

function ct_findX( obj )
{
	var x = 0;
	while (obj)
	{
		x += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	return(x);
}

function ct_findY( obj )
{
	var y = 0;
	while (obj)
	{
		y += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return(y);
}

function ct_getUrlVar( url, varName )
{
	var match = url.match( new RegExp("[&?]"+escape(varName)+"=(.+?)(&|$)" ) );

	if ( match != null )
		return match[1];
	else
		return '';
}

function ct_isIE()
{
	return window.attachEvent && ! ct_isOpera();
}

function ct_isW3C()
{
	return window.addEventListener;
}

function ct_isOpera()
{
	return window.opera;
}

function ct_browser()
{
	if ( ct_isIE() )
		return 'ie';
	
	if ( ct_isOpera() )
		return 'opera';

	return '';
}

// from http://www.htmlgoodies.com/primers/jsp/article.php/3608046
if(typeof(XMLHttpRequest)!='undefined'){
	var getAJAX = function(){ return new XMLHttpRequest(); }
} else {
	var getAJAX = function(){
		var activeXObjects = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0',
		'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
		for(var i=0; i<activeXObjects.length; i++){
			try{
				return new ActiveXObject(activeXObjects[i]);
			}catch(err){}
		}
	}
}
