/*
 * @author Konstantin Deryabin
 * @date 10:58:45 2009
 *
 */
var WhichBudget = { version: 1.0 ,options : { prefix : 'whichbudget_' , key : ''}};
/**
 * Handles requests to the WhichBudget server
 */
var WBLoader = {
	/**
	 * config params
	 */
	options : { idJS : '', idCSS : 'WhichBudget_css',  uriJS : '', uriCSS : 'http://beta.travel/widgets/css/default.css' },
	/**
	 * Get option's value
	 * @param {string} name
	 */
	getOption : function ( name ){
		if(this.options[name]) return this.options[name] ;
		else return null ;
	},

	/**
	 * Loads a script from remote server and inject it to the page
	 * @param {string} uri - uri for the script
	 * @param {string} domelm - DOM element where the script has to be injected
	 */
	loadJS: function(uri){
		if(!uri) uri = this.getOption('uriJS') ;
		uri = WhichBudget.appendQuery( uri , { key : WhichBudget.getOption('key')});

		domelm = (arguments.length > 1) ? arguments[1] : 'head' ;
		if (uri) {
			called = document.createElement("script");
			called.id = this.getOption('idJS');
			called.type = 'text/javascript';
			if( ref = this.append(domelm, called)){
				// mootools + IE>=7 tweak : to force script loading
				ref.src = uri;
			}
		}
	},
	/**
	 * Loads a css script from remote server and inject it to the page
	 * @param {string} uri - uri for the script
	 * @param {string} domelm - DOM element where the script has to be injected
	 */
	loadCSS :  function ( uri  ){
		if(!uri) uri = this.getOption('uriCSS') ;
		uri = WhichBudget.appendQuery( uri , { key : WhichBudget.getOption('key')});
		domelm = (arguments.length > 1) ? arguments[1] : 'head' ;
		if (uri){
			called = document.createElement("link");
			called.id = this.getOption('idCSS');
			called.type = 'text/css';
			called.rel = 'stylesheet';
			called.href = uri;
			return this.append(domelm, called);
		}else{
			//return null ;
			//alert( 'Error :: no tag - no call');
		}
	},
	/**
	 * Append loaded html to DOM
	 * @param {string} parentNode - tag name of a DOM element where the loaded script should be injected
	 * @param {Object} elm - element to add
	 */
	append : function( parentNode , elm){
		// Check if the element allready exists
		//id yes remove it
		if( document.getElementById(elm.id) ) WhichBudget.remove( elm.id )
		switch( parentNode ){
			case 'body' :
				return document.body.appendChild(elm);
			break;
			default :
				if( h = document.getElementsByTagName('head')){
					return h[0].appendChild(elm);
				}
			break;
		}
	}
}
WhichBudget.loader = WBLoader ;
WhichBudget.initialize = function ( options ){
	this.options = options ;
}
WhichBudget.toQuery = function( params){
		qs='';
		t = [];rtnType = 'query';
		if( arguments.length>1){
			switch(arguments[1]){
				case 'raw' : rtnType =  arguments[1] ;
				break;
			}
		}
		for( var key in params ){
			if( typeof( params[key]) != 'function') t[t.length] = key+'='+params[key] ;
		}
		if(t.length>0) qs = t.join('&');
		return (rtnType == 'query') ? qs : t ;
	}
/**
 * Append passed in parameters object to
 * @param {Object} params
 */
WhichBudget.appendQuery = function( uri, params ){
	wq = this.toQuery( params );
	uri += ( uri.indexOf('?') != -1  ?  '&' : '?' ) + wq
		return uri ;
}
WhichBudget.$ = function(id){
	if(typeof(id) == 'string') ref = document.getElementById(id) ;
	else ref = id ;
	if (ref) {
		return ref ;
	}else{
		return null ;
	}
}
WhichBudget.prefix$ = function(id){
	if(typeof(id) == 'string'){
		id = this.getOption('prefix')+id ;
		ref = document.getElementById(id) ;
	}
	else ref = id ;
	if (ref) {
		return ref ;
	}else{
		return null ;
	}
}
WhichBudget.getBrowser = function(){
		_a = navigator.userAgent ;
		_b = null ;
		if( /MSIE/i.test(_a) ){
			_b = 'ie' ;
		}else if(/Firefox/.test(_a)){
			_b = 'ff';
		} else if(/Opera/.test(_a)){
			_b = 'opera';
		} else if( /Safari/.test(_a)){
			_b = 'safari' ;
		}
		return _b ;
}
/**
 *
 * @param {string} name
 * @param {string} object name to get the value of a property
 */
WhichBudget.getOption = function ( name ){
	rtn = false ;
	if( arguments.length > 1 ){
		// get sub object properties
		// this library should be a object then
		sublib = arguments[1];
		so = eval(  'this.'+sublib ) ; // reference to
		if( so ){
			if(so.options[name]) rtn = so.options[name] ;
		}
	}else{
		if(this.options[name]) rtn = this.options[name] ;
	}
	return rtn ;
}
/**
 *
 * @param {string} name
 * @param {string} object name to get the value of a property
 */
WhichBudget.setOption = function ( name, value ){
	if( arguments.length > 2 ){
		// get sub object properties
		// this library should be a object then
		sublib = arguments[2];
		so = eval(  'this.'+sublib ) ; // reference to
		if (so) {
			return so.options[name] = value;
		}
	}else{
		return this.options[name] = value ;
	}
	return false;
}
WhichBudget.injectAfter = function( newElement, refElement){
	if(typeof(refElement)== 'string') refElement = this.$(refElement);
  	refElement.parentNode.insertBefore(newElement, refElement.nextSibling);
}
WhichBudget.injectBefore = function( newElement, refElement ) {
	if(typeof(refElement)== 'string') refElement = this.$(refElement);
	refElement.parentNode.insertBefore(newElement, refElement);
}
WhichBudget.injectBottom = function( newElement, refElement ) {
	if(typeof(refElement)== 'string') refElement = this.$(refElement);
	refElement.appendChild(newElement);
}
WhichBudget.replaceElement = function( newElement, refElement ) {
	if(typeof(refElement)== 'string') refElement = this.$(refElement);
	refElement.parentNode.replaceChild(newElement);
}
WhichBudget.setHTML = function( refElement, content ) {
	t = refElement ;
	if(typeof(refElement)== 'string') refElement = this.$(refElement);
	if(!refElement){
		this.debug( 'Element not found ' + t );
	}else{
		refElement.innerHTML = content;
	}
}
WhichBudget.remove = function( id ) {
	e = this.$(id) ;
	if(e){
		e.parentNode.removeChild(e);
	}
}
WhichBudget.debug = function( msg  ){
	return ;
	/*msg = 'WhichBudget::debug >>> ' + msg ;
	if (console != undefined) {
		console.debug(msg);
	}else {
		alert(msg);
	}
	*/
}

WhichBudget.setAPIKey = function( key ){
	this.setOption( 'key', key );
}

/**
 *
 * @param {array} vals
 * @param {array} keys for 1st paramseters
 */
WhichBudget.arrayToObject = function( vals ){
	if(arguments.length > 1){
			keys = arguments[1] ;
	}else{
		keys = [] ;
	}
	o = {}
	for(i=vals.length-1 ;i>=0;i--){
		k = keys[i]  ?  keys[i] : i ;
		o[k] = vals[i] ;
	}
	return o ;
}
/**
 * as JS going nut when encounter that
 * @param {array} vals
 */
WhichBudget.objectSource = function( o ){
	s = new Array();
	rtn = null ;val = null ;
	if(typeof(o) !== null && typeof(o) == 'object'){

		for( i in o){
			l = s.length ; val = null ;
			s[l] = '' + i  + ':' ;
			switch( typeof(o[i])){
				case "string":	val = '"' + o[i] + '"' ; break;
				case "number" : val =  o[i] ; break;
				case  "object" :
					_s = [] ;
					for( k in o[i] ){
							_l = _s.length ; _val = '' ;
							_s[_l] = '' + k  + ':' ;
							switch( typeof(o[i][k])){
								case "string":	_val = '"' + o[i][k] + '"' ; break;
								case "number" : _val =  o[i][k] ; break;
								case  "object" :
									//val = this.objectSource( o[i] );
								break;
							}
							_s[_l] += '' + _val ;
					};
					if( _s.length > 0){
						val = '{' + _s.join(',')+ '}' ;
						_s = null ;
					};
				break;
			};
			s[l] += '' + val ;
		};
		if(s.length > 0) rtn = '{' + s.join(',')+ '}' ;
	}
	return rtn ;
}

/**
 * Create a DOM element
 * @param {string} tag
 * @param {Object} - element attributes as an object
 * @return elemnt
 */
WhichBudget.createElement = function( tag ) {
	e = document.createElement(tag) ;
	if(arguments.length > 1 ){
		attribs = arguments[1] ;
		for( v in attribs){ e.setAttribute( v, attribs[v] )}
	}
	return e ;
}

WhichBudget.setStyles = function( el, style ){
	e = WhichBudget.$(el);
	if(e){
		for(o in style){
			e.style[o]= style[o]  ;
		}
	}
}
/**
 *
 * @param {string} eid - element ID
 */
WhichBudget.onView = function(eid){
	el = this.$(eid) ;
	if(el){
		ov_parent = WhichBudget.$('whichbudget_list') ;

		ov_col  = ov_parent.childNodes ;
		ov_h = 0 ;
		for(k=0;k < ov_col.length; k++){
				if( ov_col[k].firstChild.id == eid ){
					break;
				};
				ov_h += ov_col[k].scrollHeight +1 ; // 1 px for border
		};
		
		ov_parent.scrollTop = ov_h ;
		//el.scrollIntoView(true);
	}
}
/**
 * Show or hide a message box.
 * While showing a message box is superposed on an element
 * @param {string|html object} eid - element ID or html oject reference of the element on which the loading box is supreposed
 * @param {string} action - values [show|hide] for showing and hiding a loading box
 */
WhichBudget.msgBox = function( eid , action){
	ebase = WhichBudget.$(eid);
	if(!ebase){
		return ;
	}
	mbid = WhichBudget.getOption('prefix') + 'mbox';
	mbel = WhichBudget.$(mbid) ;
	if( !mbel ){
		// create message box element
		mbel = WhichBudget.createElement('div', { id : mbid }) ;
		mbel.innerHTML = '&nbsp;' ;
		WhichBudget.injectBottom( mbel , 'whichbudget_container' );
	}
	if(!mbel){
		return ;
	}else{
		switch( action){
			case 'show' :
				// get sizes & position
				mbparams = {} ;
				if(e){
					_parent  = e.parentNode ;
					//mbparams['width'] = _parent.offsetWidth    + 'px';
					mbparams['width'] = '100%'; // change fix value if position is relative
					mbparams['height'] = ebase.offsetHeight + 'px' ;
					mbparams['top']  = '-' + (  ebase.offsetHeight )  + 'px' ;
					mbparams['left'] = '0px';
					mbparams['display'] = 'block' ;
					mbparams['position'] = 'relative' ;
					WhichBudget.setStyles( mbel , mbparams);
					mbparams = null ;
				};
			break;
			case 'hide' :
				mbparams = {} ;
				mbparams['top'] = '-500px' ;
				mbparams['left']  = '-500px';
				mbparams['display'] = 'none' ;
				mbparams['position'] = 'absolute' ;
				WhichBudget.setStyles( mbel , mbparams );
				mbparams = null ;
			break;
		}
	}
}
/**
 * Strip WB prefix & return a value
 */
WhichBudget.getWBValue = function( str ){
	_prfx = this.getOption('prefix');
	_reg = new RegExp( _prfx , 'i');
	return str.replace(_reg, '');
}
/**
 * Flights Catcher
 */
var RoutesWidget = {
	options : { idJS : 'WhichBudget_JS',
		appid : 'routes_widget',
		baseURI : 'http://beta.travel/widgets/RoutesWidget.php',
		key :'',
		direction : 'from',
		iso : '',
		iata : '',
		finalURI : 'http://www.whichbudget.com/en/',
		basketActive : 1 ,
		lang : '',
		charset : 'utf-8',
		trg : 'wb',
		selection :{ iata_from : '', iata_to : '' , iso_from : '', iso_to : '', block_from : 0 , block_to : 0  , direction : '' }},
	getOption : function( name ){
		return WhichBudget.getOption( name , 'RoutesWidget');
	},
	setOption : function( name, value ){
		return WhichBudget.setOption( name , value , 'RoutesWidget');
	},
	setSelection : function( params ){
		switch( params.exec ){
			case 'reset' :
				// set up default values back
				params = this.getOption('registry');
			break ;
			case 'clear' :
				// clean all data
				params = { iso_from : '',iso_to : '',iata_from : '',iata_to : '', block_from : 0, block_to : 0, direction : ''};
			break ;
		}
		if( params.iso_from != undefined ) this.options.selection['iso_from'] = params.iso_from  ;
		if( params.iso_to != undefined ) this.options.selection['iso_to'] = params.iso_to ;
		if( params.iata_from != undefined) this.options.selection['iata_from'] = params.iata_from ;
		if( params.iata_to != undefined ) this.options.selection['iata_to'] = params.iata_to ;
		if( params.block_from != undefined ) this.options.selection['block_from'] = params.block_from ;
		if( params.block_to != undefined ) this.options.selection['block_to'] = params.block_to ;
		if( params.direction != undefined ) this.options.selection['direction'] = params.direction ;

	},
	toQuery : function( params){
		qs='';t = [];rtnType = 'query';
		if( arguments.length>1){
			switch(arguments[1]){
				case 'raw' : rtnType =  arguments[1] ;
				break;
			}
		}
		for( key in params ){
			if(params[key]) t[t.length] = key+'='+params[key] ;
		}
		if(t.length>0) qs = t.join('&');
		return (rtnType == 'query') ? qs : t ;
	},
	isEmptySelection:function(){
		s = this.getOption('selection');
		res = true ;
		for(opt in s ){
			if (s[opt]) {
				res = false;
				break;
			}
		}
		return res ;
	},
	/**
	 * Get a value of a parameter selection
	 * @param {string} name
	 */
	getSelection : function( name ){
		return ( this.options.selection[name] != undefined ) ? this.options.selection[name] : false ;
	},
	/**
	 * Prepare and sends a request to the server toget a list of countries
	 * @params object params - with following keys
	 *  iata - iata code
	 *  feel - direction ( from|to)
	 *  end - choosen irport iata code
	 */
	getCountries :function( params ){

		q = new Array();
		qs = '';
		if( params['update'] != '') params['update'] = 'country' ;
		if( params.iata ){
			if (this.options.mode == 'custom') {
				_p = {};
				_p['iata_' + params.feel] =  params.iata  ;
				this.setSelection( _p );

				this.options.iata = params.iata;
				if(1== this.getOption('basketActive')){
					this.setBasketCustom( WhichBudget.$(params.iata).innerHTML , params.feel ); // basket
				}
				params['mode'] = 'custom';

			}else {
				if (1 == this.getOption('basketActive')) {
					if (WhichBudget.prefix$(params.iata))
						this.setBasket(WhichBudget.prefix$(params.iata).innerHTML, params.feel); // basket
				}
			}
		}else if(this.options.mode == 'custom') {
			if (1 == this.getOption('basketActive')) {
				this.setBasketCustom(null, null);
			}
			params['mode']='custom';
		}
		uri = WhichBudget.appendQuery( this.options.baseURI , params ) ;
		this.load( uri , true );
	},
	/**
	 * Prepare and sends a request to the server to get a list of airports for the passed in paramaters country
	 * @params object params - with following keys
	 *  iso - country ISO code
	 *  feel - direction ( from|to )
	 *  end - choosen airport iata code
	 */
	getAirports :function( params ){
		q = new Array();
		qs = '';
		if( '' != params['update']) params['update'] = 'airport' ;
		if(!params) return ;
		if( this.options.mode == 'custom' ){
			_p = {};
			_p['iso_' + params.feel] =  params.iso ;
			_p['iata_' + params.feel] =  '' ;
			this.setSelection( _p );

			this.options.iso =  params.iso ;
			this.options.iata = '' ;
			if (1 == this.getOption('basketActive')) {
				this.setBasketCustom(WhichBudget.$(params.iso).innerHTML, params.feel); // set country name
			}
			params['mode']='custom';
		}

		uri = WhichBudget.appendQuery( this.options.baseURI , params ) ;
		this.load( uri , true  ); // load URI & show wait message meanwhile
	},
	/**
	 * Inject a content returned by the server to the document
	 * @param {String} eid - element ID after which return content should be added
	 * @param {string} content - html content
	 */
	handleAirportRequest : function( eid, content){
			prefix = WhichBudget.getOption('prefix') ;
			WhichBudget.remove( prefix+'airports') ;
			el = WhichBudget.createElement('div', { id : prefix + 'airports'});
			el.innerHTML = content ;
			eid = prefix+eid ;
			//WhichBudget.injectAfter( el, WhichBudget.$(eid).parentNode );
			WhichBudget.injectAfter( el, eid );
			WhichBudget.msgBox(prefix + 'list', 'hide');
			WhichBudget.onView(eid);

	},
	/**
	 * Shortcut for WhichBudget.loader.loadJS function
	 * @param {Object} uri
	 */
	load : function( uri ){
		showWait =  null ;

		if(arguments.length > 1){
			if( arguments[1] === true) showWait = true ;
			else if( arguments[1] === false ) showWait = false ;
		}
		switch( showWait ){
			case true :
				WhichBudget.msgBox( WhichBudget.getOption('prefix')+'list', 'show');
			break;
			case false :
				WhichBudget.msgBox( WhichBudget.getOption('prefix') + 'list', 'hide');
			break ;
		}
		WhichBudget.loader.loadJS(uri) ;
	},
	/**
	 *
	 * @param {Object} options
	 */
	initialize : function( options ){
		//extend or modify predefined options

		for( opt in options ){
			if( typeof(opt) == 'object'){
				for ( subopt in opt) {
					this.options[opt][subopt] = opt[subopt];
				}
			}else{
				if(options[opt]) this.options[opt] = options[opt] ;
			}
		}
		if( document.charset )
		{
			this.setOption( 'charset' , document.charset );
		}else if( document.characterSet ){
			this.setOption( 'charset' , document.characterSet );
		}
		WhichBudget.setAPIKey( this.getOption('key'));
		if( !this.getOption('lang')){
			this.setOption('lang', 'en');
		}
		if(this.getOption('idJS')){
			WhichBudget.loader.options.idJS = this.options.idJS;
		}
		if(this.getOption('baseURI')){
			if(this.getOption('lang')){
				this.options.baseURI = WhichBudget.appendQuery(  this.options.baseURI , { lang : this.getOption('lang') , charset : this.getOption('charset') , trg : this.getOption('trg') }) ;
			}
			WhichBudget.loader.options.uriJS = this.options.baseURI;

		}
		if(this.getOption('uriCSS')){
			WhichBudget.setOption('uriCSS', this.getOption('uriCSS'), 'loader' );
		}
		if(this.getOption('idCSS')){
			WhichBudget.setOption('idCSS', this.getOption('idCSS'), 'loader' );
		}
		if( 'en' != this.getOption('lang')){
			_uri = this.getOption('finalURI') ;
			this.setOption('finalURI', _uri.replace( /\/en\//i, "/"+this.getOption('lang')+"/" ))  ;
		}


		q = new Array();qs = '';

		if( false === this.isEmptySelection() ){
			if(!this.getSelection('iso_from')){
				this.setSelection('block_from', 0);
				this.setSelection('direction', '');
			}
			if(!this.getSelection('iso_to')){
				this.setSelection('block_to', 0);
				this.setSelection('direction', '');
			}
			d = this.getSelection('direction') ; // set preselected way
			if(d){
				if((d=='from' || d=='to') === true ) this.setOption('direction', d);
			}
			/*o = this.getIni( 'default' );
			qs = '?'+ this.toQuery(o);
			*/q = this.getIni( 'default' );

		}
		if( WhichBudget.getOption('mode', 'RoutesWidget')){
			/* qs += ( qs.indexOf('?') != -1  ?  '&' : '?'  ) + 'mode=' + this.options.mode ; */
			q['mode'] = this.options.mode  ;
		}
		uri = WhichBudget.appendQuery( this.options.baseURI, q);
		WhichBudget.loader.loadCSS( WhichBudget.appendQuery( WhichBudget.getOption('uriCSS', 'loader') , {origin:this.getOption('appid')}) );
		WhichBudget.RoutesWidget.load(uri);
	},
	/**
	 * Get preselected options
	 * @param {string} way - direction [from|to] , any other value will make the function return
	 * all preselected options in a special format. Useful for sending a request to the Server
	 * @return object
	 */
	getIni : function( way ){
		qs = '' ;
		params = {} ;nspaces={};
		switch(way){
			case 'from' : nspaces = {
				iso_from: 'iso',
				iata_from: 'iata',
				block_from: 'block'
			};
			break;
			case 'to' : nspaces = {
				iso_to: 'iso',
				iata_to: 'iata',
				block_to: 'block'
			};
			break;
			default :
				d = this.getSelection('direction');
				if(!d) d = this.getOption('direction');
				revway = (d=='from') ? 'to':'from' ;
				nspaces['iso_'+d]= 'iso';
				nspaces['iata_'+d]= 'iata' ;
				nspaces['block_'+d]= 'block';
				nspaces['iso_'+revway]= 'slc[iso]';
				nspaces['iata_'+revway]= 'slc[iata]' ;
				nspaces['block_'+revway]= 'slc[block]';

			break;
		}
		nspaces['direction'] = 'feel' ; // common
		//nspaces['lang']= 'lang';

		/*
		 * Check if selection is done
		 */
		if( false === this.isEmptySelection() ){
			s = this.getOption('selection') ;
			for( k in nspaces){
				if(s[k]) params[nspaces[k]] = s[k] ;
			}
		}
		return params ;
	},
	/**
	 * Set a text in a basket container
	 * @param {string} text -  Airpot or Country name
	 * @param {string} way - direction ( from | to )
	 */
	setBasket : function( text , way){
		line = null ;
		d = (WhichBudget.getOption('direction', 'RoutesWidget')) ;
		if (way) {
			if (d == 'from') {
				// line 1 - FROM, line 2 - TO
				line = (way == 'from') ? 1 : 2;
			}
			else
				if (d == 'to') {
					line = (way == 'to') ? 1 : 2;
				}
		}

		switch( line ){
			case 1:
				WhichBudget.setStyles( 'whichbudget_basket_direction' , {	visibility: 'hidden'}  );
				WhichBudget.setStyles( 'whichbudget_basket_out' , {visibility : 'visible'}  );
				WhichBudget.setStyles( 'whichbudget_basket_reselect' , {visibility : 'visible'}  );
				WhichBudget.setStyles( 'whichbudget_basket_destination', {visibility : 'visible'});
				WhichBudget.setHTML (  'whichbudget_basket_out' , text );
			break;
			case 2:
				WhichBudget.setStyles( 'whichbudget_basket_validate' , {visibility : 'hidden'} ); // activated when response from the server with destination uri is recieved
				//WhichBudget.setStyles( 'whichbudget_basket_destination', {visibility : 'visible'});
				WhichBudget.setStyles( 'whichbudget_basket_in' , {visibility : 'visible'}  );
				WhichBudget.setHTML (  'whichbudget_basket_in' , text );

			break;
			default :
				//reinitilize
				col = ['whichbudget_basket_out' , 'whichbudget_basket_reselect', 'whichbudget_basket_validate', 'whichbudget_basket_in', 'whichbudget_basket_destination'] ;
				for(i=col.length -1;i>=0;i--){
					WhichBudget.setStyles( col[i] , {visibility : 'hidden'} );
				}
				WhichBudget.setHTML('whichbudget_basket_out', '');
				WhichBudget.setHTML('whichbudget_basket_in', '');
				WhichBudget.setStyles( 'whichbudget_basket_direction' , {visibility : 'visible'}  );

			break;
		}
	},
	setBasketLabels : function( d ){
		sbl_rf = ( d == 'from') ? 'to':'from' ;
		WhichBudget.setHTML( 'whichbudget_basket_intro' , WhichBudget.getOption( d + '_intro', 'RoutesWidget' )) ;
		WhichBudget.setHTML( 'whichbudget_basket_direction' , '[' + WhichBudget.getOption( sbl_rf , 'RoutesWidget' ) + ']');
		WhichBudget.setHTML( 'whichbudget_basket_destination' , WhichBudget.getOption( sbl_rf , 'RoutesWidget' ) );
		sbl_rf = null ;
	},
	/**
	 * Enable or disable basket label(s)
	 * @param {array} aid - arrai with basket buttons' id
	 * @param {string} action -  action [enable|disable]
	 */
	renderBasketLabels : function( aid , action){
		rbl_styles = {} ;
		switch(action){
				case 'disable' :
				 rbl_styles = { display : 'none' } ;
				break;
				case 'enable' :
					rbl_styles = { display : 'inline' } ;
				break;
		}
		for( k = aid.length-1;k>=0;k--){ WhichBudget.setStyles( aid[k], rbl_styles );}
	},
	updateFinalURI : function( uri ){
		WhichBudget.msgBox('whichbudget_list', 'hide');
		fin_tmp =  WhichBudget.$('whichbudget_basket_validate') ;
		fin_tmp.setAttribute( 'href' , uri ) ;
		fin_tmp.setAttribute( 'target' , '_blank' ) ;
		fin_val_uri = fin_tmp =null ;
		WhichBudget.setStyles( 'whichbudget_basket_validate' , {visibility : 'visible'}  );
	},
	getFinalURI : function( params ){
			params['update'] = 'uri';
			uri = WhichBudget.appendQuery( this.options.baseURI , params ) ;
			this.load( uri , true ); // load URI & show wait message meanwhile
	},
	finalize : function( params ){
		WhichBudget.msgBox('whichbudget_list', 'hide');
		if(this.options.mode == 'custom'){
			_p = {};
			_p['iata_' + params.feel] =  params.iata  ;
			this.setSelection( _p );
			if (1 == this.getOption('basketActive')) {
				this.setBasketCustom(WhichBudget.$(params.iata).innerHTML, params.feel);
			};
			return ;
		}
		q = ''; __q = [];
		if (params.iata && params.feel) {
			endway = (params.feel == 'to') ? 'from' : 'to';
			__q[params.feel] = params.iata ;
			if (!params.end) {
				return false ;
			}
			else {
				__q[endway] = params.end ;
			}
		}else{
			return false ;
		}
		if(__q){
			__q['trg'] = this.getOption('trg');
			if (1 == this.getOption('basketActive')) {
				this.setBasket(WhichBudget.prefix$(params.iata).innerHTML, params.feel);
				// disable redirect button if server response takes a long time to answer
				WhichBudget.setStyles( 'whichbudget_basket_validate' , {visibility : 'hidden'}  );
			};
			this.getFinalURI(__q);
		}
		return false ;
	},
	colEvents : {
		load_options_lng : {
			eventType : 'run',
			func : function(){
				el = WhichBudget.$('whichbudget_lng')
				if(el){
					lng = el.innerHTML ;
					if(lng){
						lng_arr = lng.split('|');
						WhichBudget.RoutesWidget.addOptionsArray( lng_arr , ['to','from','to_intro','from_intro']);
					}
				}

			}
		},
		basket_direction : {
			eventType : 'click' ,
			element : 'whichbudget_basket_direction',
			func : function(){
			optd = WhichBudget.getOption( 'direction', 'RoutesWidget' );
			bd_rf = (optd == 'from') ? 'to':'from' ;
			WhichBudget.setOption( 'direction', bd_rf, 'RoutesWidget') ;
			WhichBudget.setOption( 'iso', '', 'RoutesWidget') ;
			WhichBudget.setOption( 'iata','', 'RoutesWidget') ;

			if (WhichBudget.getOption('mode', 'RoutesWidget') == 'custom') {
				WhichBudget.RoutesWidget.setSelection({
					exec: 'reset'
				});
				if (1 == WhichBudget.getOption('basketActive', 'RoutesWidget')) {
					WhichBudget.RoutesWidget.setBasketLabels(bd_rf);
					WhichBudget.RoutesWidget.setBasketCustom(null, null);
				}
			}else{
				if (1 == WhichBudget.getOption('basketActive', 'RoutesWidget')) {
					WhichBudget.RoutesWidget.setBasketLabels(bd_rf);
					WhichBudget.RoutesWidget.setBasket(null, null);
				}
			}
			params = WhichBudget.RoutesWidget.getIni( bd_rf ) ;
			params['feel'] = bd_rf ;
			//params['update'] = '';
			/*
			 * Apply some filters
			 */
			if( !params.block ){ params.iso = '';params.iata = '';} //otherwise preselcted options blocking direction changing
			WhichBudget.RoutesWidget.getCountries( params );
			}
		},
		basket_reselect: {
			eventType: 'click',
			element : 'whichbudget_basket_reselect',
			func: function(){
				if( WhichBudget.getOption('mode', 'RoutesWidget') == 'custom'){
					WhichBudget.RoutesWidget.setSelection( { exec : 'reset' } );
					if (1 == WhichBudget.getOption('basketActive', 'RoutesWidget')) {
						WhichBudget.RoutesWidget.setBasketCustom(null, null);
					}
				}else{
					if (1 == WhichBudget.getOption('basketActive', 'RoutesWidget')) {
						WhichBudget.RoutesWidget.setBasket(null, null);
					}
				}
				WhichBudget.setStyles( 'whichbudget_basket_direction' , {visibility : 'visible'}  );
				WhichBudget.setOption( 'iso', '', 'RoutesWidget') ;
				WhichBudget.setOption( 'iata', '', 'RoutesWidget') ;
				w = WhichBudget.getOption('direction', 'RoutesWidget') ;
				/*
				 * Use preselected params only if block option is enabled
				 */
				if( WhichBudget.RoutesWidget.getSelection('block_'+w)==1){
					params = WhichBudget.RoutesWidget.getIni( w ) ;
				}else{
					params = {} ;
				}
				params['feel'] = w ;
				//params['update'] = '' ;
				WhichBudget.RoutesWidget.getCountries( params );
			}
		}
	},
	dispatchEvents : function(){
		_run = null ;
		if(arguments.length > 0){ _run = arguments[0] ; } // run just specific event
		for( o in this.colEvents){
			if ( true === ( _run == null || _run == o)){

				if ( this.colEvents[o].eventType != 'run') {
					el = WhichBudget.$(this.colEvents[o].element) ;
					if(el){
						eval('WhichBudget.$(this.colEvents[o].element).on'+this.colEvents[o].eventType+' = this.colEvents[o].func') ;
					}
				}else {
					// simply run a function
					this.runEvent(o);
				}
				if(_run != null) break;
			}
		}
	},
	addEvent : function( name , object){
		this.colEvents[name] = object ;
	},
	runEvent : function( ename ){
		if(this.colEvents[ename]){
			ref = this.colEvents[ename] ;
			return ref.func();
		}
	},
	/**
	 * Array of params to add as Options
	 * @param {Object} arr
	 */
	addOptionsArray : function( vals ){
		if (vals.length > 0) {
			if (arguments.length > 1) {
				keys = arguments[1];
			}
			else {
				keys = vals;
			}
			for (i = keys.length - 1; i >= 0; i--) {
				WhichBudget.setOption(keys[i], vals[i], 'RoutesWidget');
			}
		}
	},
	setBasketCustom : function( text , way){
		line = null ;
		d = this.getOption('direction') ;
		if (way) {
			if (d == 'from') {
				line = (way == 'from') ? 1 : 2
			}
			else
				if (d == 'to') {
					line = (way == 'to') ? 1 : 2;
				}
		}

		switch( line ){
			case 1:
				WhichBudget.setStyles( 'whichbudget_basket_direction' , {	visibility: 'hidden'}  );
				WhichBudget.setStyles( 'whichbudget_basket_out' , {visibility : 'visible'}  );
				WhichBudget.setStyles( 'whichbudget_basket_reselect' , {visibility : 'visible'}  );
				WhichBudget.setStyles( 'whichbudget_basket_destination', {visibility : 'visible'});
				WhichBudget.setHTML (  'whichbudget_basket_out' , text );

			break;
			case 2:
				WhichBudget.setStyles( 'whichbudget_basket_destination', {visibility : 'visible'});
				//WhichBudget.setStyles( 'whichbudget_basket_validate' , {visibility : 'visible'} );
				WhichBudget.setStyles( 'whichbudget_basket_in' , {visibility : 'visible'}  );
				WhichBudget.setHTML (  'whichbudget_basket_in' , text );

			break;
			default :
				//reinitilize

				col = ['whichbudget_basket_out' , 'whichbudget_basket_reselect', 'whichbudget_basket_validate', 'whichbudget_basket_in', 'whichbudget_basket_destination'] ;
				for(i=col.length -1;i>=0;i--){
					WhichBudget.setStyles( col[i] , {visibility : 'hidden'} );
				}

				WhichBudget.setHTML('whichbudget_basket_out', '');
				WhichBudget.setHTML('whichbudget_basket_in', '');
				WhichBudget.setStyles( 'whichbudget_basket_direction' , {visibility : 'visible'}  );

			break;
		}
	},
	/**
	 * Generate a JS code initilising RoutesWidget Lib
	 * ! Do not forget to upgrade
	 * @param String key - API key
	 */
	genCallAPI : function(){
		if(arguments.length > 0) WhichBudget.setOption( 'key', arguments[0], 'RoutesWidget' );
		if( this.getOption('direction')== this.getSelection('direction')) this.setSelection('direction', '');
		keys = [ 'key', 'lang', 'trg', 'selection'] ;
		source = '';
		code = {} ;
		_p = '' ;
		for(i = keys.length -1;i >= 0; i--){
			if( this.options[keys[i]] != null ){
				code[keys[i]] = this.options[keys[i]]  ;
			}
		}

		_p =  WhichBudget.objectSource( code ) ;
		if(_p.indexOf( '{') == 0) _p = _p.substr(1, _p.length-2);
		source = '<script type="text/javascript" src="http://beta.travel/widgets/js/whichbudget.js">' +
		'</script>' +
		'<script type="text/javascript">' +
		'/*<![CDATA[*/' +
		'try{WhichBudget.RoutesWidget.initialize({' + _p + '})}catch(err){}'+
		'/*]]>*/' +
		'</script>' ;
	return source ;
	}
}
WhichBudget.RoutesWidget = RoutesWidget ;