var History = {};


History._get_script_path = function ()
{
	var scripts = document.getElementsByTagName ( "script" );
	var l = scripts.length;

	var path = scripts [ l - 1 ].src;
	var pos = path.lastIndexOf ( "/" );
	if ( pos == -1 )
		path = "";
	else
		path = path.slice ( 0, pos + 1 );

	return path;
};


History._load = function ()
{
	History._is_ie = ( document.all && navigator.userAgent.toLowerCase().indexOf ( 'msie' ) != -1 );

	var path = History._get_script_path ();
	History._blank_page = path + "history_blank.html";

	History._data_storage = [];
	
	if ( History._is_ie )
		History._createIFrame ();

	document.write ( '<form style="display: none;"><input id="HistoryDataText" type="text" value="" \/><\/form>' );
};


History.setBlankPage = function ( url )
{
	History._blank_page = url;
};


History.init = function ()
{
	History._saved_location = History.getCurrentLocation();

	setInterval ( History._checkLocation, 100 );

	setTimeout ( History._init_done, 200 );
};


History._init_done = function ()
{
	var hdt = document.getElementById ( "HistoryDataText" );
	
	if ( hdt.value )
		History._data_storage  = hdt.value.parseJSON();

	History._callListener();
};


History._createIFrame = function ()
{
	var loc = History.getCurrentLocation();
	
	History._adding = true;
	
	document.write ( "<iframe style='border: 2px; width: 1px; "
                               + "height: 1px; position: absolute; bottom: 0px; "
                               + "right: 0px; display: none;' "
                               + "name='HistoryFrame' id='HistoryFrame' src='" + History._blank_page + "?" + loc + "'>"
                               + "<\/iframe>" );

	History._iframe = document.getElementById ( "HistoryFrame" );

	window._os3_history_cb = History._iframeLocationChanged;
};


History.getCurrentLocation = function ()
{
	var loc = window.location.hash;
	if ( loc.length > 0 && loc.charAt ( 0 ) == '#' )
		loc = loc.slice ( 1 );
	return loc;
};


History._callListener = function ()
{
	if ( ! History.listenerCallback ) return;

	var id = History.getCurrentLocation ();
	var dict = History._str2dict ( id );
	var data;

	if ( typeof dict [ "__data_key" ] != "undefined" )
	{
		var key = parseInt ( dict [ "__data_key" ] );
		data = History._data_storage [ key ];
		delete dict [ "__data_key" ];
	}

	History._listener_call = true;
	History.listenerCallback ( dict, data );
	History._listener_call = false;
};


History.setListener = function ( listener )
{
	History.listenerCallback = listener;
};


History.add = function ( dict, data )
{
	if ( History._listener_call ) return;

	if ( data )
	{
		var key = History._data_storage.length.toString();
		History._data_storage.push ( data );
		dict [ "__data_key" ] = key;

		var s = History._data_storage.toJSONString();
		var is = document.getElementById ( "HistoryDataText" );
		is.value = s;
	}

	var id = History._dict2str ( dict );
	window.location.hash = id;
	History._saved_location = id;

	if ( History._is_ie )
	{
		History._adding = true;
		History._iframe.src = History._blank_page + "?" + id;
	}
};


History._dict2str = function ( dict )
{
	var str = "";
	var is_first = true;
	
	var k, v;
	for ( k in dict )
	{
		v = dict [ k ];
		if ( typeof ( v ) == 'function' ) continue;

		if ( is_first ) is_first = false;
		else str += ",";
		
		str += k;
		if ( v != null && v != undefined )
		{
			v = v.toString();
			str += "=" + History._escape_value ( v );
		}

	}

	return str;
};


History._str2dict = function ( str )
{
	var tok;

	var dict = {};

	str = History._lstrip ( str );

	while ( str.length > 0 )
	{
		// cerco la virgola divisoria
		var cpos = str.indexOf ( "," );
		while ( cpos < str.length - 1 && str.charAt ( cpos + 1 ) == ',' )
			cpos = str.indexOf ( ",", cpos + 2 );

		if ( cpos == -1 )
		{
			tok = str;

			str = ""
		}
		else
		{
			tok = str.slice ( 0, cpos );

			str = str.slice ( cpos + 1 );
			str = History._lstrip ( str );
		}

		// splittiamo sull'uguale
		var splt = tok.split ( "=" )
		var k = splt [ 0 ];
		var v = History._join ( "=", splt.slice ( 1 ) );
		v = v.replace ( ",,", "," );

		dict [ k ] = v;
	}

	return dict;
};


History._escape_value = function ( v )
{
	return v.replace ( ",", ",," );
};


History._lstrip = function ( s )
{
	while ( s.length > 0 && s.charAt ( 0 ) == ' ' )
		s = s.slice ( 1 )
	return s;
};


History._join = function ( sep, arr )
{
	var l = arr.length;
	if ( l == 0 ) return "";
	
	var s = arr [ 0 ];
	for ( var i = 1; i < l ; i++ )
		s += sep + arr [ i ];

	return s;
};


History._iframeLocationChanged = function ( id )
{
	if ( History._adding )
	{
		History._adding = false;
		return;
	}

	if ( id.length > 0 && id.charAt ( 0 ) == '?' )
		id = id.slice ( 1 )

	window.location.hash = id;
	History._saved_location = id;

	History._callListener ();
};


History._checkLocation = function ()
{
	var loc = History.getCurrentLocation();
	if ( loc == History._saved_location )
		return;

	History._saved_location = loc;

	if ( History._is_ie )
		History._iframe.src = History._blank_page + "?" + loc;
	else
		History._callListener();
};


History._load();

