var WBExplore = {
	options: {
		baseURI: '/cmd/',
		direction: 'from',
		lang: 'en',
		currency: 'EUR',
		trg: 'whichbudget',
		p : '' ,
		redirectBlank : false ,
		tracker : "",
		selection: {
			iata_from: '',
			iata_to: '',
			iso_from: '',
			iso_to: '',
			block_from: 0,
			block_to: 0,
			direction: ''
		},
		elements : {
			container: {
				id: 'widget_container'
			},
			main: {
				id: 'widget_explore' ,
				tag : 'div',
				'class' : 'widget_explore'
			}
		},
		basket : {
			elements: {
				main: { id: 'widget_basket', tag: 'div', 'class' : 'widget_basket' },
				direction: {
					id: 'direction',
					'class' : 'direction',
					tag: 'select',
					subElements: [{
						tag : 'option',	
						value: 'from',
						'text': 'from'
					}, {
						tag : 'option',
						value: 'to',
						text: 'to'
					}]
				},
				reselect: {
					id: 'reselect',
					tag: 'span',
					'class': 'reselect'
				},
				destination: {
					id: 'destination',
					tag: 'span',
					'class': 'destination'
				},
				basketOut: {
					id: 'basket_out',
					tag: 'span',
					'class': 'basket_out'
				},
				basketIn: {
					id: 'basket_in',
					tag: 'span',
					'class' : 'basket_in'
				},
				validate: {
					id: 'validate',
					tag: 'button',	
					'class': 'validate button_orange'
				},
				intro: {
					id: 'intro',
					tag: 'span',
					'class' : 'intro'
				},
				inviteSelect: {
					id: 'invite_select',
					tag: 'span' ,
					'class': 'invite_select'
				}
			},
			text : {
				to: 'to',
				from: 'from',
				to_intro: 'I want to fly to',
				from_intro: 'I want to fly from',
				intro: 'I want to fly',
				search: 'Search',
				change: 'Change',
				invite_select: 'Select country/airport from the list'
			},
			direction : 'from'
		},
		list : { elements : {
			main : {'id': 'widget_list', 'class' : 'widget_list'},
			list: { 'id': 'country_list', 'class' : 'country_list'},
			elementContainer: { tag: 'h3'},
			element: { 'class': 'country'},
			subElementContainer : { 'class' : 'slide'},
			subElement: { 'class' : 'airport'}
			},
			ns : {
				elementContainer : 'CONTAINER_' ,
				element : 'C_' ,
				subElementContainer : 'SLIDER_' ,
				subElement : 'A_'
			}
		},
		animation : {
			elements : {
				scroller : { id : 'widget_list' },
				loader : { tag : 'div' , 'class' : 'loading_full'}
			}
		},
		search : {
			elements: {
				main : {
					id: 'search',
					tag: 'input',
					type : 'text', 
					name :'search',
					'class' : 'explore_search'
				}
			},
			errorClass : 'explore_error',
			text : { default_phrase : '...type country here' }
		},
		
		tools : {
			elements: {
				main : {
					id: 'widget_tools',
					tag: 'div',
					'class' : 'widget_tools'
				}
			}
		},	
		refresh : {
			elements: {
				main : {
					id: 'refresh',
					tag: 'span',
					'class' : 'explore_refresh'
				}
			},
			text : { default_phrase : 'Reset'}
		}
	},
	/*
	 * instead of using  iata_from , iata_to, and other options
	 * we use env variables without checking all the time direction
	 */
	env: {
		isoStart: null,
		iataStart: null,
		isoEnd: null,
		iataEnd: null
	},
	Basket : null ,
	Search : null ,
	List : null , 
	loadedCountries: null,
	Transport : null, 
	Animation : null ,
	finalURI : null ,
	initialize: function(options){

		if (options) 
			WBHelper.setValues( this, options , 'options');

		if (!this.getOption('lang')) {
			this.setOption('lang', 'en');
		}
		if (this.getOption('baseURI')) {
			if (this.getOption('lang')) {
				this.options.baseURI = this.appendQuery(this.options.baseURI, {lang: this.getOption('lang')});
			}
		}

		
		this.validateSelection();			
		d = this.getSelection('direction'); // set preselected way
		if(d){
			if(d == 'from' || d == 'to') 
				this.setOption('direction', d);
		}
		
		this.Animation = new WBAnimation( this.options.animation );
		this.Search = new WBSearch( this.options.search );
		this.Tools.initialize( this.options.tools );
		this.Refresh.initialize( this.options.refresh );	
		// Rendering order is important	
		if( this.getOption('elements.container.id') && $( this.getOption('elements.container.id'))){
			this.container =  $( this.getOption('elements.container.id')) ;
			this.container.empty();
		} else{ 
			this.container =  document.body ;
		} ;
		
		this.render( this.container );
		
		this.setOption('basket.direction', this.getOption('direction') );
		if( this.getSelection('block_'+ this.getOption("direction") ) ){
			this.setOption('basket.disableReselect' , true ) ;
		}
		this.Basket = new WBBasket( this.options.basket );		
		this.Basket.render( this.main, 'top');

		this.List  =  new WBList( this.options.list );	
		this.List.render( this.Basket.main, 'after' );
		
		this.Tools.render( this.main );
		this.Search.render( this.Tools.main , 'top');	
		this.Refresh.render( this.Tools.main );
		this.Animation.render();
		
		this.Transport  = new Request.Queue() ;
		// events handling

		// Adjust List height according to basket and tools block sizes
		WBExplore.List.main.setStyle( 'height' , WBExplore.main.offsetHeight - WBExplore.Basket.main.offsetHeight - WBExplore.Tools.main.offsetHeight  );				
		this.Basket.addEvent( 'beforeRenderBasket', function( action ){			
			if( action == 2 ){
				// disable while ajax is triggered to get the redirection page
				// see afterRenderBasket event below
				WBExplore.Basket.validate.removeEvents("click");
			}
		});
		this.Basket.addEvent( 'afterRenderBasket', function( action ){			
			WBExplore.List.main.setStyle( 'height' ,  WBExplore.main.offsetHeight - WBExplore.Basket.main.offsetHeight - WBExplore.Tools.main.offsetHeight  ) ;
			if( action == 2 ){
				WBExplore.iniFinalURI();				
				WBExplore.Basket.validate.addEvent( 'click' , function(){ 
					WBExplore.redirect()
				});	
			}
		});
		this.Basket.direction.addEvent('change', function(){
			WBExplore.changeDirection();
			WBExplore.load();
			WBExplore.loadWBCF();
		});
		if( !this.getOption('basket.disableReselect')){
			this.Basket.reselect.addEvent('click', function(){
				WBExplore.emptySelection();
				WBExplore.clear();
				WBExplore.load();
				WBExplore.loadWBCF();
			})
		};
		this.List.addEvent( 'getSubElement' , function( params ){
				// attache airport associated event
				params.element.setProperties( { 'text' : params.phrase } ) ; 
				params.element.addEvent( 'click', function() {
					WBExplore.getCountries({ 'airport': params.code });
					WBExplore.loadWBCF();
				});
			});
		this.List.addEvent( 'appendElement' , function( params ) {		
				// inject flag
				new Element( 'span', { 'class': 'flag spr-' + params.code.toLowerCase() }).inject( params.element, 'top');
				// attache country associated event
				params.element.addEvent( 'click' , function()
				{
					var p = {	'country': params.code };
					p.type = 'in';
					if (WBExplore.eget('iataStart')) {
						p.airport = WBExplore.eget('iataStart');
						p.type = 'connected';
					}
					WBExplore.getAirports(p);
					WBExplore.loadWBCF();
				} );
			});
		this.List.addEvent( 'appendSubElement' , function(  params ){
				
				// append slider to collections
				WBExplore.Animation.appendSlider( params.element.id, params.code );
				// Change country assicoated event
				countryElem = $( WBExplore.List.getDOMId( 'elementContainer', params.code ) ) ;
				countryElem.removeEvents();
				countryElem.addEvent('click', function(e){
					if (e) e.stop();
					WBExplore.Animation.toggleSlider( WBExplore.List.getCode( this.id ));
					WBExplore.Animation.scrollTo(this.id);
					WBExplore.loadWBCF();
				});
				WBExplore.Animation.trigger( params.code, 'slideIn');
				WBExplore.Animation.scrollTo( countryElem.id );	
			}) ;
		
		this.Refresh.main.addEvent('click', function(){
			d = WBExplore.getSelection('direction')== 'to' ? 'to' : 'from' ;
			WBExplore.setOption( 'direction' , d );
			WBExplore.Basket.setDirection( d );
			WBExplore.emptySelection();
			WBExplore.clear();
			WBExplore.load();
		});
		
		this.Search.main.addEvents({
			'focus': function(){
					if (this.value == WBExplore.Search.getDefaultText()) 
						this.value = "";
					else 
						this.select();
					WBExplore.Search.clear();
			},
			'blur': function(){
					this.value = WBExplore.Search.getDefaultText();
					WBExplore.Search.clear();
				},
			'keyup': function(){
					WBExplore.Search.removeError();
					if (this.value != WBExplore.Search.getDefaultText() && this.value != '') {
						code = WBExplore.Search.find(this.value , WBExplore.loadedCountries );
						if (code){
							WBExplore.Animation.scrollTo( WBExplore.List.getDOMId( 'elementContainer', code ));
							if (WBExplore.Search.trial >= WBExplore.Search.ambiguity) {
								if (WBExplore.Animation.isSet(code)) {
									WBExplore.Animation.trigger(code, 'slideIn');
								}
								else {
									celem = $( WBExplore.List.getDOMId( 'elementContainer', code )) ;
									celem.fireEvent('click');
									celem.removeEvents();
								}
							}
						}
						else 
							if (!code) {
								WBExplore.Search.showError();
							}
					}
					else 
						WBExplore.Animation.scroller.toTop();
				},
				'keydown': function(e){
					if (e.key == 'enter') {
						if (this.value != WBExplore.Search.getDefaultText() && this.value != '') {
							code = WBExplore.Search.result;
							if (code) {
								if (WBExplore.Animation.isSet(code)) 
									WBExplore.Animation.trigger(code, 'toggle');
								else 
									$( WBExplore.List.getDOMId( 'elementContainer', code )).fireEvent('click');
							}
							
						}
					}
				}
			});
		this.Transport.addEvents( {
			'request': function(){
				WBExplore.Animation.showLoader( WBExplore.main );
			},
			'complete' : function(){
				WBExplore.Animation.hideLoader();
			}
		});	
		
		this.load();
	},
	load: function(){
		// Setting env variables
		d = this.getOption('direction') ;
		
		isoStart = this.getSelection('iso_'+ d );
	
		iataStart=  this.getSelection('iata_'+ d );
		blockStart =  this.getSelection('block_'+ d);
		
		r = (d=="from") ? "to" : "from" ;
		
		isoEnd =  this.getSelection('iso_'+ r );
		iataEnd =  this.getSelection('iata_'+ r );
		blockEnd =  this.getSelection('block_'+ r );
		
		if ( isoStart && iataStart) {
			_lparams = { airport: iataStart } ;
			
			// get airport name for basket preset
			this.eset( 'isoStart', isoStart);			
			this.getAirport( _lparams ); 

			if (blockEnd && isoEnd) {
			// countries' choice may be limited to 1 country 
			// by block_from or block_to value or simply by				
				_lparams.country = isoEnd;					
			}			
			this.getCountries( _lparams );
			
			if(iataEnd){
			// if destination airport is given wait until the country airpoirts list loads
			// and add choosen destination to the basket by triggering attached event	
				aid = this.List.getDOMId(  'subElement', iataEnd );					
				iLimit = 100 ;
				period = (function(){ 
					if( $(aid) ){
						$(aid).fireEvent("click");
						$clear(period);
					}
					if(--iLimit <= 0)
						$clear(period);
				}).periodical(100);
			}
			
			
		}else if (isoStart && blockStart) {
			this.getCountries( {country: isoStart} ); // airports are loaded automaticly when only 1 country is displayed
		}else if (isoStart) {
			this.getCountries();
			this.getAirports({
				country: isoStart,
				'type': 'in'
			});
		}else {
			this.getCountries();
		}
	},
	clear: function(){
		this.eset('iataStart', null);
		this.eset('iataEnd', null);
		this.eset('isoStart', null);
		this.eset('isoEnd', null);
		this.Basket.clear();
		this.Animation.clear();
		this.List.clear();
		this.loadedCountries = null;
	},
	changeDirection: function(){
		this.clear();
		rev = (this.getOption('direction') == 'from') ? 'to' : 'from';
		this.setOption('direction', rev);
		this.Basket.setDirection( rev );
		
	},	
	Handler: {
		running: false,
		queue: [],
		countries: function(r){
			WBExplore.loadedCountries = r.countries;
			WBExplore.Basket.renderBasket();
			WBExplore.List.clear();
			WBExplore.List.appendElements(  WBExplore.loadedCountries );
			WBExplore.Animation.scroller.toTop();
			// if one country is displayed load automaticly airports of the country
			rev =  WBExplore.getOption('direction') == "from" ? "to" : "from";
			if( WBExplore.loadedCountries.length == 1){
				$( WBExplore.List.getDOMId( 'elementContainer', WBExplore.loadedCountries[0].code )).fireEvent('click');				
			}else if( WBExplore.eget('isoStart') && WBExplore.getSelection( 'iso_' + rev )){
				$( WBExplore.List.getDOMId( 'elementContainer', WBExplore.getSelection( 'iso_' + rev ) )).fireEvent('click');							
			}
		},
		airports: function(r){
		
			WBExplore.Basket.renderBasket();
			cid = (WBExplore.eget('isoEnd') ? WBExplore.eget('isoEnd') : WBExplore.eget('isoStart'));
			WBExplore.List.appendSubElement( cid , r.airports );
			// append to basket the airport name if it's preset by triggering attached to the airport event
			if(WBExplore.eget('iataEnd')){
				$( WBExplore.List.getDOMId( 'subElement', WBExplore.eget('iataEnd'))).fireEvent('click');
			}
		},
		airport: function(r){
			WBExplore.Basket.addItem(r.airports[0].phrase);
			WBExplore.Basket.renderBasket();
		},
		process: function(name, params){
			if (!this.running) {
				this.running = true;
				this[name].run(params);
				this.running = false;
				this.runNext();
			}
			else {
				this.queue.push(new Hash({
					'fn': name,
					'params': params
				}));
			}
			
		},
		runNext: function(){
			if (this.queue.length > 0 && !this.running) {
				name = this.queue[0]['fn'];
				params = this.queue[0]['params'];
				this.queue.shift();
				this.process(name, params);
			}
		}
	},
	_set : function( name, value ){
		WBHelper.setValue( name, value, this ) ;
		return this._get(name);	
	},
	_get : function( name ){
		return WBHelper.getValue( name, this );
	},
	eget : function(name){
		return this._get( 'env.'+name); 
	},	
	eset : function( name , value ){
		return this._set( 'env.'+name , value );			
	},
	setOption : function( name, value ){
		return this._set( 'options.'+ name, value );
	},
	getOption : function( name ){
		return this._get( 'options.'+ name  );
	},
	
	render: function(container, position){
		
		this.main = WBHelper.createElement(this.options.elements.main);
		if (!container) 
			container = document.body;
		if (position) 
			position = '';
		this.main = this.main.inject(container, position);
	},
	toQuery: function(params){
		qs = '';
		t = [];
		
		for (key in params) {
			if (params[key]) 
				t[t.length] = key + '=' + params[key];
		}
		if (t.length > 0) 
			qs = t.join('&');
		return qs;
	},
	appendQuery: function(uri, params){
		uri += (uri.indexOf('?') != -1 ? '&' : '?') + this.toQuery(params);
		return uri;
	},
	isEmptySelection: function(){
		s = this.getOption('selection');
		res = true;
		for (opt in s) {
			if (s[opt]) {
				res = false;
				break;
			}
		}
		return res;
	},
	getSelection: function(name){
		return this._get('options.selection.' + name);
	},
	/**
	 * 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){
	
		if (!params) 
			params = {};
		if (!params.country) 
			params.cmd = 'GetCountries';
		else 
			params.cmd = 'GetCountry';
		
		if (this.eget('isoStart') && !this.eget('iataStart') && params.airport) {
			this.eset('iataStart', params.airport);
			this.Basket.addItem($( this.List.getDOMId('subElement', params.airport)).innerHTML);
		}else if (this.eget('isoEnd') && params.airport){
			this.Basket.addItem($( this.List.getDOMId('subElement', params.airport) ).innerHTML);
			this.eset('iataEnd', params.airport);
		}
		
		if (!this.eget('isoEnd')){
		
			url = this.appendQuery(WBExplore.getOption('baseURI'), params);
			if( this.getOption('direction') == 'to' ) // Add direction=destination to url request on TO
					url = this.appendQuery(url, {direction:'destination'});
			WBExplore.Transport.addRequest('RGetCountries', new Request.JSON({
				'url': url,
				method: 'get',
				onSuccess: function(r, xml){
					WBExplore.Handler.process('countries', arguments);
				}
			}));
			WBExplore.Transport.send('RGetCountries');
		}
		else {
			
			WBExplore.Basket.renderBasket();
			WBExplore.Animation.hideLoader();
		}
	},
	getAirport: function(params){
	
	
		if (!params) 
			params = {};
		params.cmd = 'GetAirport';
		url = this.appendQuery(WBExplore.getOption('baseURI'), params);
		if(params.airport){
			this.eset( 'iataStart' , params.airport ) ;
		}
		WBExplore.Transport.addRequest('RGetAirports', new Request.JSON({
			'url': url,
			method: 'get',
			onSuccess: function(r, xml){
				WBExplore.Handler.process('airport', arguments);
			}
		}));
		WBExplore.Transport.send('RGetAirports');
	},
	
	getAirports: function(params){
	
		if (!params) 
			params = {};
		params.cmd = 'GetAirports';
		
		if (!WBExplore.eget('iataStart')) {
			WBExplore.eset('isoStart', params.country);
		}
		else 
			if (WBExplore.eget('isoStart') && WBExplore.eget('iataStart')) {
				WBExplore.eset('isoEnd', params.country);
			}
		
		
		url = this.appendQuery(WBExplore.getOption('baseURI'), params);
		if( this.getOption('direction') == 'to' ) // Add direction=destination to url request on TO
			url = this.appendQuery(url, {direction:'destination'});
		WBExplore.Transport.addRequest('RGetAirports', new Request.JSON({
			'url': url,
			method: 'get',
			onSuccess: function(r, xml){
				WBExplore.Handler.process('airports', arguments);
			}
		}));
		WBExplore.Transport.send('RGetAirports');
	},
	
	Tools : {
		options: {
			elements: {
				main : {
					id: 'widget_tools',
					tag: 'div'
				}
			}
		},
		main: null,	
		clear: function(){
		},
		initialize : function( options ){
			WBHelper.setValues( this, options, 'options');
		},
		render : function( container , position ){
			this.main = WBHelper.createElement(this.options.elements.main );
			if (!container) 
				container = document.body;
			if( position)	
				position = '' ;
			this.main = this.main.inject( container, position );
		}	
	},
	Refresh : {
		options: {
			elements: {
				main : {
					id: 'refresh',
					tag: 'span'
				}
			},
			text : { default_phrase : 'Reset'}
		},
		initialize : function( options ){
			WBHelper.setValues( this, options, 'options');
		},
		render : function( container , position ){
			this.main = WBHelper.createElement(this.options.elements.main );
			if (!container) 
				container = document.body;
			if( position)	
				position = '' ;
			this.main.set( 'text' , this.options.text.default_phrase ); 
			this.main = this.main.inject( container, position );
		}	
	},
	loadWBCF: function() {
		// Fire event for load WBCheapFlights
		var param = {
			lang: WBExplore.getOption( 'lang' ),
			currency: WBExplore.getOption( 'currency' ),
			originCountry: ( this.options.direction == 'from' ) ? WBExplore.env.isoStart : WBExplore.env.isoEnd,
			origin: ( this.options.direction == 'from' ) ? WBExplore.env.iataStart : WBExplore.env.iataEnd,
			destinationCountry: ( this.options.direction == 'from' ) ? WBExplore.env.isoEnd : WBExplore.env.isoStart,
			destination: ( this.options.direction == 'from' ) ? WBExplore.env.iataEnd : WBExplore.env.iataStart
		};
		window.fireEvent( 'loadWBCF', param );	
	},
	validateSelection : function(){
		if( this.isEmptySelection() )
			return ;
		
		d = this.getSelection('direction') ;
		if(!d) 
			d = this.getOption("direction") ; 
		else if(d != 'from' && d != 'to' ){
			d = this.getOption("direction") ;
			this.setOption("selection.direction", "");
		}
		r = (d=="from") ? "to" : "from" ;

		isoStart = this.getSelection('iso_'+ d );
		iataStart=  this.getSelection('iata_'+ d );
		blockStart =  this.getSelection('block_'+ d);
		isoEnd =  this.getSelection('iso_'+ r );
		iataEnd =  this.getSelection('iata_'+ r );
		blockEnd =  this.getSelection('block_'+ r );

		if (!isoStart){
			this.setOption('selection.block_' + d, 0);
			this.setOption('selection.iata_' + d, 0);
			this.setOption('selection.iso_' + r, 0);
		}
		if( isoStart && !iataStart){
			this.setOption("selection.iso_" + r, "");
			this.setOption("selection.iata_" + r, "");			
		}
		if (!isoEnd ){
			this.setOption('selection.block_'+ r, 0);
			this.setOption('selection.iata_' + r, 0);
		}		
	},
	emptySelection : function(){
		d = this.getOption("direction");
		if( 1 == this.getSelection("block_"+d))
			return ;
		
		this.setOption('selection.block_to' , 0);
		this.setOption('selection.iata_to' , 0);
		this.setOption('selection.iso_to' , 0);		
		this.setOption('selection.block_from' , 0);
		this.setOption('selection.iata_from' , 0);
		this.setOption('selection.iso_from' , 0);
		//this.setOption('selection.direction' , "");
	},
	iniFinalURI : function(){
		// attach redirect URI to the validate button
		Redirect.setSite( WBExplore.getOption('trg') );
		if( this.getOption("direction") == "from" ){
			Redirect.set( {origin: WBExplore.eget( 'iataStart'), destination: WBExplore.eget( 'iataEnd') } );		
		}else{
			Redirect.set( {origin: WBExplore.eget( 'iataEnd') , destination: WBExplore.eget( 'iataStart')  } );		
		}
				
		if(WBExplore.getOption('p'))
			Redirect.set( { p : WBExplore.getOption('p')} );
		if( this.getOption("trg") == "beta" ){
			Redirect.set( {
				page: 'Prices',
				// get text from Basket element
				originText: WBExplore.Basket.getContentText( 'origin' ),
				destinationText: WBExplore.Basket.getContentText( 'destination' )
			} );
			this.finalURI = Redirect.get( 'Prices' );
		}else{
			Redirect.set( {page: 'Routes'} );
			// done thru ajax so wait a bit until the response will be returned
			Redirect.get( 'Routes' );
		}
			
	},
	setRedirectURI : function( uri ){
		this.finalURI = uri ;
	},
	getRedirectURI : function( ){
		return this.finalURI ;
	},
	redirect : function(){
		target =  WBExplore.options.redirectBlank ? "_blank" : ""  ;
		if( this.getOption("trg") == "whichbudget" ){
			this.finalURI = Redirect.getRemote('Routes');
		}
		this.fireEvent('onBeforeRedirect', this.finalURI );		

		// Use common Redirect for redirect on beta
		if( this.getOption('trg') == 'beta' ) {
			Redirect.go( 'Prices' );
			return;
		}
		
		switch( target ) {
			case '_blank':
				window.open( this.finalURI);
				break;
			case '_parent':
				parent.window.location.href = this.finalURI;
				break;
			default:
				document.location.href = this.finalURI ;
				break;
		}
	},
	setTrackerUrl : function(){
		sURL = this.getRedirectURI();
		if(this.getOption( "tracker") ){
			trackingURL = this.getOption( "tracker");
			if (trackingURL.indexOf('tc.tradetracker') != -1){	
				trackingURL += '&u=';
			}else{
				if (trackingURL.indexOf('campaignID') != -1){
					trackingURL += '&redirectURL=';
				}else{
					trackingURL += '&r='
				}
			}
			this.setRedirectURI( trackingURL + escape(sURL) ) ;
		}
		return null ;
	}
}
// attache events handling to the object
$extend(WBExplore, new Events) ;
