// Common Javascript

/**
 * Initialize all common class and common method
 */
var Common = new Class( {
	
	Implements: Options,
		
	options: {
		Class: ['GLOBALS', 'CookieManager', 'Dictionary', 'RX', 'Redirect', 'Rewrite', 'Cache', 'CurrencyService', 'Help']
	},
	
	initialize: function() {
		this.autoload();
	},
	
	autoload: function() {
		// Init class
		this.options.Class.each( function( Class ) {
			eval( Class + " = new " + Class );
		} );
	},
	
	setGlobalCursor: function( type ) {
		document.body.setStyle( 'cursor', type );
	},
	
	toObject: function( queryString ) {
		var obj = {};
		this.query = queryString.split( '&' );
		for( var i = 0; i < this.query.length; i++ ) {
		    var tmp = this.query[i].split( '=' );
		    if( tmp[0] == '' )
		    	continue;
		    if( !tmp[1] ) {
		        tmp[1] = true;
		    } else if( tmp[1] == 'false' ) {
		        tmp[1] = false;
		    } else if( tmp[1] == 'true' ) {
		        tmp[1] = true;
		    }
		    obj[tmp[0]] = tmp[1];
		}
		return obj;
	},
	
	truncate: function( s, l, trunc ) {
		var str = '';
		var l_str = s.length;
		var l_trunc = ( $type( trunc ) != false ) ? trunc.length : 0;
		
		if( l_str > l + l_trunc ) {
			str = s.substr( 0, l - l_trunc );
			if( $type( trunc ) != false ) str = str + trunc;
			return str;
		} else {
			return s;
		}
	},
	
	round: function( n, l, full ) {
		var num = '';
		var n = n.toFloat();
		num = n.round( l ).toString();
		if( full == true || $type( full ) == false ) {
			var m = num.match( /\.([0-9]+)/ );
			if( m != null ) {
				var d = l - m[1].length;
				if( d > 0 ) {
					for( var i = 0; i < d; i++ ) {
						num += '0';
					}
				}
			}
		}
		return num;
	},
	
	random: function( array ) {
		
		return array.sort( ( function() { return Math.round( Math.random() );} ) );
		
	},
	
	toggleLoader: function( params ) {
		
		var el = params.el;
		var name = params.name;
		var options = {
			elements : {
				loader : {
					'class' : 'loading_full'
				}
			}
		};
		if( $type( params.element ) == 'element' )
			options.elements.loader.element = params.element;
		
		if( $type( WBAnimation ) == 'class' ) {
			var name = 'loader' + name;
			if( $type( params.state ) != false )
				$GLOBALS[name].state = params.state;
			
			if( $type( $GLOBALS[name] ) == false ) {
				$GLOBALS[name] = new WBAnimation( options );  
				$GLOBALS[name].render();
				$GLOBALS[name].state = false;
			}
			if( $GLOBALS[name].state == false ) {
				$GLOBALS[name].state = true;
				$GLOBALS[name].showLoader( el );			
			} else {
				$GLOBALS[name].state = false;
				$GLOBALS[name].hideLoader();
			}
		}
		
		// By default scroll element to top
		if( $type( $(el) ) != false && params.scroll2top == true ) $(el).scrollTo( 0, 0 );
		
	},
	
	sort: function( object, params ) {

		if( $type( object.json ) == 'object' && $type( object.sub_obj ) != false ) {
			var json = object.json[object.sub_obj];
		} else {
			return false;
		}

		var field = ( $type( params.field ) != false ) ? params.field : 'id';
		var type =( $type( params.type ) != false ) ? params.type : 'string';
		var order =( $type( params.order ) != false ) ? params.order : 'asc';
		
		var json_length = json.length;
		for( var i = 0; i < json_length; i++ ) {
			for( var j = 0; j < json_length; j++ ) {
				if( this.setSortable( json[i][field], type ) < this.setSortable( json[j][field], type ) ) {
					var tmp = json[i];
					json[i] = json[j];
					json[j] = tmp;
				}
			}
		}
		
		if( order == 'desc' ) json.reverse();

		object.json[object.sub_obj] = json;
		
		return object.json;
		
	},
	
	setSortable: function( value, type ) {
		
		switch( type ) {
			case 'int':
				value = value.toInt();
				break;
			case 'float':
				value = value.toFloat();
				break;
			case 'time':
				value = value.replace(/:/,"").toInt();
				break;
			case 'string':
			default:
				value = value;
				break;
		}
		
		return value;
		
	},
	
	center: function( el, dynamic ) {
	
		el.setStyles( {
			top: window.getSize().y / 2 + window.getScroll().y - el.getSize().y / 2,
			left: window.getSize().x / 2 + window.getScroll().x - el.getSize().x / 2
		} );
		
		if( $type( dynamic ) != false && dynamic == true ) {
			window.addEvents( {
				scroll: function() {
					Common.center( el, false );
				},
				resize: function() {
					Common.center( el, false );
				}
			} );
		}
		
	},
	
	scrollTo: function( mixed ) {
		
		if( $type( this.scollWindow ) == false )
			this.scrollWindow = new Fx.Scroll( window );
		
		if( $type( mixed ) == 'element' || ( $type( mixed ) == 'string' && $type( $(mixed) ) == 'element' ) )
			this.scrollWindow.toElement( mixed );
		else if( $type( mixed ) == 'object' )
			this.scrollWindow.set( mixed.x, mixed.y );
		else if( $type( mixed ) == 'string' )
			this.scrollWindow['to' + mixed.capitalize()]();
			
	},
	
	blinking: function( element, options ) {
		
		if( $type( options ) == false ) options = {};
		
		var colorFrom = options.colorFrom || '#FFCC66';
		var colorTo = options.colorTo || '#FFFFFF';
		var howMany = options.howMany || 5;
		
		// get original background-color
		var bgcolor = element.getStyle( 'background-color' );
		
		this.blink = new Fx.Tween( element, {
			fps: 30,
			link: 'chain',
			duration: 200,
			onChainComplete : function() {
				// restore original background at the end
				element.setStyle( 'background-color', bgcolor );
				element.fireEvent( 'complete' );
			}
		} );

		for( var i = 0; i < howMany; i++ ) {
			this.blink.start( 'background-color', colorTo, colorFrom );
			this.blink.start( 'background-color', colorFrom, colorTo );
		}
		
	},
	
	toggleDisplay: function( ele, force ) {
		
		var state = '';
		var forceIt = ( $type( force ) == false ) ? null : force;
		
		if( forceIt != null ) {
			$(ele).setStyle( 'display', ( forceIt == true ? 'block' : 'none' ) );
			state = forceIt == true ? 'open' : 'close';
			return state;
		}
		
		if( $(ele).getStyle( 'display' ) == 'none' ) {
			$(ele).setStyle( 'display', 'block' );
			state = 'open';
		} else {
			$(ele).setStyle( 'display', 'none' );
			state = 'close';
		}
		
		return state;
		
	},
	
	isNull: function( value ) {
		if( value == '' || value == null || value == 'null' )
			return true;
		else
			return false;
	},
	
	gps2dec: function( g, p, s, d ) {
		var degree = parseInt( g );
		var minute = parseInt( p ) / 60;
		var second = parseInt( s ) / 3600;
		var symbole = d == 'S' || d == 'W' ? '-' : '+';
		var coordinate = parseFloat( symbole + ( degree + minute + second ) );
		
		// Check value
		if( ( d == 'N' || d == 'S' ) && ( coordinate > 90 || coordinate < -90 ) )
			return false;
		else if( ( d == 'E' || d == 'W' ) && ( coordinate > 180 || coordinate < -180 ) )
			return false;
		else
			return coordinate ;
	},
	
	dec2gps: function( decimal, type ) {
		if( type != 'lat' && type != 'lon' )
			return false;
		else if( type == 'lat' && ( decimal > 90 || decimal < -90 ) )
			return false;
		else if( type == 'lon' && ( decimal > 180 || decimal < -180 ) )
			return false;
		
		var numbers = decimal.toString().split( '.' );
		
		var g = Math.abs( parseInt( numbers[0] ) );
		
		if( type == 'lon' )
			var d = parseInt( numbers[0] ) >= 0 ? 'N' : 'S';
		else
			var d = parseInt( numbers[0] ) >= 0 ? 'E' : 'W';
		
		if( numbers[1] == undefined ) {
			var p = 0;
			var s = 0;
		} else {
			var min = parseFloat( 0 + '.' + numbers[1] ) * 60;
			var p = parseInt( min );
			var sec = min.toString().split( '.' );
			var s = ( sec[1] == undefined ) ? 0 : parseInt( parseFloat( 0 + '.' + sec[1] ) * 60 );
		}
		
		return {g: g, p: p, s: s, d: d}
	},
	
	timestamp: function( utc ) {
		var date = new Date();
		
		if( typeof( utc ) == undefined || utc == false )
			return Math.round( date.getTime() / 1000 );
		
		date.setFullYear( date.getUTCFullYear() );
		date.setMonth( date.getUTCMonth() );
		date.setDate( date.getUTCDate() );
		date.setHours( date.getUTCHours() );
		date.setMinutes( date.getUTCMinutes() );
		date.setSeconds( date.getUTCSeconds() );
		date.setMilliseconds( date.getUTCMilliseconds() );
		
		return Math.round( date.getTime() / 1000 );
	}
	
} );

/**
 * Set a var to global with $GLOBALS like php
 */
var GLOBALS = new Class( {
	
	Implements: Options,
	
	options: {
		// Global options
	},
	
	initialize: function() {
		$GLOBALS = new Array();
	}

} );

var Cache = new Class( {
	
	Implements: Options,
	
	options: {
		// Cache options
	},
	
	initialize: function() {
		$GLOBALS['Cache'] = new Array();
	},
	
	set: function( item, key ) {
		$GLOBALS['Cache'][key] = item;
	},
	
	get: function( key ) {
		return $GLOBALS['Cache'][key];
	},
	
	del: function( key ) {
		delete $GLOBALS['Cache'][key];
	}
	
} );

/*
 * Extends Request.JSON for use cache
 */
var JSONCache = new Class( {

    Extends: Request.JSON,

    get: function( options, key ) {
	
		this.key = key;
		if( !Cache.get( this.key ) )
			this.parent( options );
		else {
			this.fireEvent( 'request' );
			this.success( JSON.encode( Cache.get( this.key ) ) );
		}
		
    },
	
	success: function( text ) {
    	
		if( !Cache.get( this.key ) ) {
			this.response.json = JSON.decode( text, this.options.secure );
			Cache.set( this.response.json, this.key );
			this.onSuccess( this.response.json, text );
		} else {
			this.onSuccess( JSON.decode( text, this.options.secure ), text );
		}
			
	}

} );

/*
 * Extends Cookie for write specific cookie
 */
var CookieManager = new Class( {
	
	Implements: Options,
	
	options: {
		// Cookie options
		path: '/',
		duration: 365,
		secure: false
	},
	
	initialize: function() {
		
		this.options.domain = window.location.href.match( /http\:\/\/(.*?)\/.*$/ )[1].replace( 'www', '' );
		
	},
	
	get: function( name ) {
	
		return Cookie.read( name );
	
	},
	
	set: function( item, options ) {
		
		var $this = this;
		
		if( $type( options ) == 'object' ) {
			// save current options
			var cOptions = this.options;
			this.setOptions( options );
		}

		if( $type( item ) == 'object' ) {
			new Hash( item ).each( function( value, key ) {
				if( $type( value ) != false ) {
					Cookie.write( key, value, $this.options );
				}
			} );
			// reset options
			this.setOptions( cOptions );
			return true;
		} else {
			return false;
		}
	
	},
	
	remove: function( mixed ) {
		
		if( $type( mixed ) == 'string' ) {
			Cookie.dispose( mixed, this.options );
		} else if( $type( mixed ) == 'array' ) {
			mixed.each( function( el ) {
				Cookie.dispose( el, this.options );
			} );
		} else {
			return false;
		}
		
	}
	
} );

var RX = new Class( {
	
	Implements: Options,
	
	options: {
		// RX uri
		uri: '/rx/',
		// RX Params
		params: {
			origin: null,
			destination: null,
			lang: 'en',
			airline: null,
			depDate: null,
			retDate: null,
			//passengers: 18,
			currency: 'EUR',
			p: null,
			product: 'beta.travel',
			channel: null,
			sourceURL: null,
			test: false
		}
	},
	
	initialize: function() {
		var params = {
			origin: CookieManager.get( 'origin' ) || null,
			destination: CookieManager.get( 'destination' )|| null,
			lang: CookieManager.get( 'lang' ) || 'en',
			currency: CookieManager.get( 'currency' ) || 'EUR',
			p: CookieManager.get( 'p' ) || null,
			sourceURL: window.location.href.match( /http\:\/\/.*?(\/.*?)$/ )[1]
		};
		this.setOptions( {params: params} );
	},
	
	set: function( params ) {
		this.setOptions( {params: params} );
	},

	get: function() {
		return this.options.uri + '?' + Hash.toQueryString( this.options.params );
	}
	
} );

var Redirect = new Class( {
	
	Implements: Options,
	
	options: {
		site: 'whichbudget',
		link: {
			beta: {
				host: 'http://beta.travel',
				base: '/?page={page}&origin={origin}&destination={destination}&oneway={oneway}&lang={lang}&currency={currency}',
				depDate: '&depDate={depDate}',
				retDate: '&retDate={retDate}'
			},
			whichbudget: {
				host: 'http://www.whichbudget.com',
				base: '/?page={page}&origin={origin}&destination={destination}&lang={lang}&currency={currency}',
				depDate: '&depDate={depDate}',
				retDate: '&retDate={retDate}'
			}
		},
		params: {
			page: 'Routes',
			origin: null,
			destination: null,
			originText: null,
			destinationText: null,
			depDate: null,
			retDate: null,
			oneway: false,
			lang: 'en',
			currency: 'EUR',
			p: null
		}
	},
	
	initialize: function() {
		this.uri = new Array();
		this.options.params.lang = CookieManager.get( 'lang' ) || 'en';
		this.options.params.currency = CookieManager.get( 'currency' ) || 'EUR';
	},
	
	getParam: function( param ) {
		if( $type( this.options.params[param] ) != false )
			return this.options.params[param];
		else
			return null;
	},
	
	setSite: function( site ) {
		this.options.site = site;
	},
	
	getSite: function() {
		return this.options.site;
	},
	
	setLink: function( options ) {
		this.setOptions( {link: options} );
	},

	set: function( params ) {
		this.setOptions( {params: params} );
		CookieManager.set( {
			origin: this.options.params.origin,
			destination: this.options.params.destination
		} );
	},
	
	get: function( page ) {
		
		// whichbudget options
		if( this.getSite() == 'whichbudget' ) {
			this.uri[page] = this.options.link[this.getSite()].host;
			if( this.getParam( 'lang' ) != 'en' ) this.uri[page] = this.uri[page] + '/' + this.getParam( 'lang' );
			this.uri[page] += this.options.link[this.getSite()].base.substitute( this.options.params );
			if( this.getParam( 'origin' ) == null ) this.uri[page] = this.uri[page].replace( /&origin=/, '' );
			if( this.getParam( 'destination' ) == null ) this.uri[page] = this.uri[page].replace( /&destination=/, '' );
		}
		
		// beta options
		if( this.getSite() == 'beta' ) {
			this.uri[page] = this.options.link[this.getSite()].host;
			this.uri[page] += this.options.link[this.getSite()].base.substitute( this.options.params );
			if( this.getParam( 'depDate' ) != null ) this.uri[page] += this.options.link[this.getSite()].depDate.substitute( this.options.params );
			if( this.getParam( 'retDate' ) != null ) this.uri[page] += this.options.link[this.getSite()].retDate.substitute( this.options.params );
		}
		
		// Adding partner ID
		if( this.getParam( 'p' ) != null ) this.uri[page] += '&p=' + this.getParam( 'p' );
		
		// hasPrices false redirection
		if( this.getParam( 'hasPrices' ) != null ) this.uri[page] += '&hasPrices=' + this.getParam( 'hasPrices' );
		
		return this.uri[page];
	},
	
	go: function( page, target ) {
		
		this.setOptions( {params: {page: page}} );
		
		// Rewrite if enabled
		if( Rewrite.enabled() == true )
			var url = Rewrite.convert( this.options.params );
		else
			var url = this.get( page );

		switch( target ) {
			case '_blank':
				window.open( url );
				break;
			case '_parent':
				parent.window.location.href = url;
				break;
			default:
				document.location.href = url;
				break;
		}
	}
	
} );

var Rewrite = new Class( {
	
	Implements: Options,
	
	options: {
		RewriteEngine: true,
		extension: '.html',
		Routes: {
			pattern: '/routes/{origin}{destination}/{verbose}{extension}',
			patternow: '/routes/{origin}{destination}/{depDate}/{verbose}{extension}',
			patternrt: '/routes/{origin}{destination}/{depDate}/{retDate}/{verbose}{extension}'
		},
		CheapFlights: {
			patternfc: '/cheapflights/from{originCountry}/{verbose}{extension}',
			patterntc: '/cheapflights/to{destinationCountry}/{verbose}{extension}',
			patternfa: '/cheapflights/from{origin}/{verbose}{extension}',
			patternta: '/cheapflights/to{destination}/{verbose}{extension}',
			patternfa_tc: '/cheapflights/from{origin}/to{destinationCountry}/{verbose}{extension}',
			patternfc_ta: '/cheapflights/to{destination}/from{originCountry}/{verbose}{extension}',
			patternfc_tc: '/cheapflights/from{originCountry}/to{destinationCountry}/{verbose}{extension}'
		}
	},
	
	convert: function( params ) {
		
		var url = null;
		/*
		 * pattern basename
		 * after add letters options
		 * cheapflights
		 * fc: from country
		 * fa: from airport
		 * tc: to country
		 * ta: to airport
		 * routes
		 * ow: oneway
		 * rt: return
		 */
		var pattern = 'pattern';
		var pattern_options = new Array();
		switch( params.page ) {
			case 'CheapFlights':
				var obj = {};
				obj.lang = params.lang;
				obj.origin = params.origin;
				obj.originCountry = params.originCountry;
				obj.originText = params.originText;
				obj.destination = params.destination;
				obj.destinationCountry = params.destinationCountry;
				obj.destinationText = params.destinationText;
				
				var from = false;
				var to = false;
				if( obj.origin != null ) {
					pattern_options.push( 'fa' );
					from = true;
				} else if( obj.originCountry != null ) {
					pattern_options.push( 'fc' );
					from = true;
				}
				
				if( obj.destination != null ) {
					pattern_options.push( 'ta' );
					to = true;
				} else if( obj.destinationCountry != null ) {
					pattern_options.push( 'tc' );
					to = true;
				}
				
				var verbose_pattern = '';
				if( from == true && to == false ) {
					obj.originText = obj.originText.replace( / \(.*/, '' );
					verbose_pattern = _d( 'CHEAP FLIGHTS FROM AIRPORT' ).replace( /%s/, '{originText}' );
				} else if( from == false && to == true ) {
					obj.destinationText = obj.destinationText.replace( / \(.*/, '' );
					verbose_pattern = _d( 'CHEAP FLIGHTS TO AIRPORT' ).replace( /%s/, '{destinationText}' );
				} else if( from == true && to == true && pattern_options[0] == 'fa' && pattern_options[1] == 'tc' ) {
					obj.originText = obj.originText.replace( / \(.*/, '' );
					obj.destinationText = obj.destinationText.replace( / \(.*/, '' );
					verbose_pattern = _d( 'CHEAP FLIGHTS FROM TO' ).replace( /%1\$s/, '{originText}' ).replace( /%2\$s/, '{destinationText}' );
				} else if( from == true && to == true && pattern_options[0] == 'fc' && pattern_options[1] == 'ta' ) {
					obj.originText = obj.originText.replace( / \(.*/, '' );
					obj.destinationText = obj.destinationText.replace( / \(.*/, '' );
					verbose_pattern = _d( 'CHEAP FLIGHTS TO FROM' ).replace( /%1\$s/, '{destinationText}' ).replace( /%2\$s/, '{originText}' );
				} else if( from == true && to == true && pattern_options[0] == 'fc' && pattern_options[1] == 'tc' ) {
					obj.originText = obj.originText.replace( / \(.*/, '' );
					obj.destinationText = obj.destinationText.replace( / \(.*/, '' );
					verbose_pattern = _d( 'CHEAP FLIGHTS FROM TO' ).replace( /%1\$s/, '{originText}' ).replace( /%2\$s/, '{destinationText}' );
				}
				
				obj.verbose = this.prepare( verbose_pattern.substitute( obj ) );
				obj.extension = this.options.extension;
				
				pattern = pattern + pattern_options.join( '_' ).replace( /__/g, '_' );
				var tpl = this.options.CheapFlights[pattern];
				if( obj.lang != 'en' ) tpl = '/{lang}' + tpl;
				
				var url = tpl.substitute( obj );

				break;
			case 'Routes':
				var obj = {};
				obj.lang = params.lang;
				obj.origin = params.origin;
				obj.depDate = params.depDate;
				obj.destination = params.destination;
				obj.retDate = params.retDate;
				var verbose = _d( 'CHEAP FLIGHTS FROM TO' ).replace( /%1\$s/, '{originText}' ).replace( /%2\$s/, '{destinationText}' );
				obj.originText = params.originText.replace( / \(.*/, '' );
				obj.destinationText = params.destinationText.replace( / \(.*/, '' );
				obj.verbose = this.prepare( verbose.substitute( obj ) );
				
				if( obj.depDate != null )
					pattern_options = 'ow';
				if( obj.depDate != null && obj.retDate != null )
					pattern_options = 'rt';
				pattern = pattern + pattern_options;
				
				var tpl = this.options.Routes[pattern];
				if( obj.lang != 'en' ) tpl = '/{lang}' + tpl;
				obj.extension = this.options.extension;
				var url = tpl.substitute( obj );
				break;
		}
		
		return url;
		
	},
	
	prepare: function( str ) {
		
        str = str.replace( /\/|'|\(|\)|,|:|"/g, ' ' );
        str = str.replace( /( ){2,}/g, ' ' );
        str = str.replace( /( )/g, '-' );
        str = str.replace( /-{2,}/g, '-' );
        str = str.toLowerCase();
        
        return str;
	},
	
	enabled: function() {
		return this.options.RewriteEngine;
	}

} );

/**
 * Set translation with Dictionary like Class Dictionary
 */
var Dictionary = new Class( {
	
	Implements: Options,

	options: {
		// Dictionary options
	},
	
	initialize: function() {
		$Dictionary = new Array();
	},
	
	set: function( key, value ) {
		$Dictionary[key] = value;
	},
	
	get: function( key ) {
		if( typeof( $Dictionary[key] ) == 'undefined' )
			return null;
		else
			return $Dictionary[key];
	}

} );
// Shortcut for use Dictionary easy
var _s = function( k, v ) {
	Dictionary.set( k, v );
};
var _d = function( k ) {
	return Dictionary.get( k );
};

var CurrencyService = new Class( {
	
	Implements: Options,
	
	options: {
		selected: null,
		class_select: 'cur_select',
		button: 'cur_div',
		arrow: '.arrow',
		dom: 'active_currency',
		list: 'currency_list',
		cur: '.currency',
		open: false
	},
	
	initialize: function() {
		
		var $this = this;
			window.addEvent( 'domready', function() {
				
				if( $type( $($this.options.button) ) != false ) {
					$($this.options.button).addEvent( 'click', function() {
						$this.toggle();
						$this.build();
					} );
				}
				
			} );
		this.options.selected = CookieManager.get( 'currency' ) || 'EUR';
	},
	
	show: function() {
		$(this.options.list).setStyle( 'visibility', 'visible' );
		$(this.options.button).getElement(this.options.arrow).set( 'text', '▲' );
		this.options.open = true;
	},

	hide: function() {
		$(this.options.list).setStyle( 'visibility', 'hidden' );
		$(this.options.button).getElement(this.options.arrow).set( 'text', '▼' );
		this.options.open = false;
	},
	
	toggle: function() {
		if( this.options.open == true )
			this.hide();
		else
			this.show();
	},
	
	set: function( cur ) {
		$(this.options.selected).removeClass( this.options.class_select );
		this.options.selected = cur;
		$(this.options.dom).set( 'text', cur );
		CookieManager.set( {currency: cur} );
		Redirect.set( {currency: cur} );
		$(this.options.selected).addClass( this.options.class_select );
		window.fireEvent( 'changeCurrency' );
		this.hide();
		window.location.reload();
	},
	
	get: function() {
		return this.options.selected;
	},
	
	build: function() {
		var $this = this;
		$(this.options.list).getElements( this.options.cur ).each( function( el ) {
			el.addEvent( 'click', function() {
				if( el.id != $this.get() ) $this.set( el.id );
			} );
		} );
	}
	
} );

/**
 * Init tooltip
 * default on domready is with class help
 * additional must be include onload event
 */
var Help = new Class( {
	
	Implements: Options,
	
	options: {
		elements: '.help',
		fixed: true,
		offset: {
			x: -4,
			y: 0
		},
		loaded: false
	},
	
	initialize: function( options ) {
		
		if( $type( options ) == 'object' )
			this.setOptions( options );
		
		if( this.options.loaded == false )
			this.initOnLoad();
		else
			this.init();
	
	},
	
	initOnLoad: function() {
		
		var $this = this;
		
		window.addEvent( 'domready', function() {
			$this.init();
			$this.options.loaded = true;
		} );
		
	},
	
	init: function() {
		
		var $this = this;
		
		this.help = new Tips( this.options.elements, {
			title: function( el ) {
				el.store( 'tip:title', _d( 'HELP' ) );
			},
			text: 'title',
			showDelay: 0,
			hideDelay: 0,
			fixed: this.options.fixed,
			onShow: function( tip, hovered ) {
				tip.setStyle( 'display', 'block' );
				var y = $this.options.offset.y - tip.getSize().y;
				this.options.offset={x:$this.options.offset.x,y:y};
			}
		} );
		
	}
	
} );

/**
 * Asset a complete API
 * and test if each file not preloaded
 * 
 * 2 way for define api file:
 * 1: all file is on same host -> define host + file
 * 2: file are on different host -> define host to '' and write complete uri for each file
 */
var loadAPI = {
	
	options: {
		host: '', // eg: http://beta.travel
		JSFiles: [], // eg: ['/js/Autocompleter.js','/js/Autocompleter.Request.js','/js/Observer.js']
		CSSFiles: [] // eg: ['/css/Autocompleter.css']
	},
	
	initialize: function( options ) {
		
		this.setOptions( options );
		this.exec();
		
	},
	
	setOptions: function( options ) {
		
		this.options.host = options.host || '';
		this.options.JSFiles = options.JSFiles || [];
		this.options.CSSFiles = options.CSSFiles || [];
		
	},
	
	exec: function() {

		if( this.options.JSFiles.length > 0 )
			this.AssetJS( 0 );
		if( this.options.CSSFiles.length > 0 )
			this.AssetCSS( 0 );
		
	},
	
	AssetJS: function( index ) {
		
		var $this = this;
		
		// Get all <script> tag in page for test if is allready loaded
		this.scripts = $$('script');
		var loaded = false;
		this.scripts.each( function( tag ) {
			if( tag.src == $this.options.JSFiles[index] || tag.src == $this.options.host + $this.options.JSFiles[index] ) {
				loaded = true;
			}
		} );
		if( loaded == false )
			var js = new Asset.javascript( this.options.host + this.options.JSFiles[index], {
				onload: function() {
					if( index + 1 < $this.options.JSFiles.length )
						loadAPI.AssetJS( index + 1 );
				}
			} );
		
	},
	
	AssetCSS: function() {
		
		var $this = this;
		
		// Get all <link> & <style> tag in page for test if is allready loaded
		this.links = $$('link');
		this.styles = $$('style');
		var loaded = false;
		this.options.CSSFiles.each( function( src ) {
			$this.links.each( function( tag ) {
				if( tag.src == src || tag.src == $this.options.host + src ) {
					loaded = true;
				}
			} );
			if( loaded == false ) { // search on style code if not on link tag
				$this.styles.each( function( tag ) {
					var css = tag.innerHTML;
					$this.options.CSSFiles.each( function( src ) {
						if( css.contains( src ) || css.contains( $this.options.host + src ) ) {
							loaded = true;
						}
					} );
				} );
			}
			if( loaded == false )
				new Asset.css( $this.options.host + src );
		} );
		
	}
	
};

/**
 * Progress bar
 */
var LoadingBar = new Class( {
	Implements: [Options, Events],
	
	options: {
		element: null,
		min: 0,
		max: 100,
		value: 0,
		dimension: {
			width: 300,
			height: 30,
			backgroundColor: '#CCCCCC',
			border: '1px solid #000000'
		},
		resizable: true,
		// Events
		onComplete: null
	},
	
	initialize: function( options ) {
		if( typeof( options ) != 'object' )
			return false;
		this.setOptions( options );
		
		this.exec();
	},
	
	exec: function() {
		var $this = this;
		this.bar = typeof( this.options.element == 'string' ) ? $(this.options.element) : this.options.element;
		this.bar.setStyles( {
			width: this.options.dimension.width,
			height: this.options.dimension.height,
			border: this.options.dimension.border
		} );
		this.progressBar = new Element( 'div', {
			styles: {
				display: 'block',
				'float': 'left',
				height: this.options.dimension.height,
				backgroundColor: this.options.dimension.backgroundColor
			}
		} ).inject( this.bar );
		
		this.fxTween = new Fx.Tween( this.progressBar, {
			duration: 'short',
			onComplete: function() {
				if( $this.options.value >= 100 ) 
					$this.fireEvent( 'onComplete' );
			}
		} );
		this.apply( this.options.value );
	},
	
	apply: function( value ) {
		if( value > this.options.max )
			value = this.options.max;
		this.options.value = this.calculate( value );
		var size = Math.round( this.options.value * this.options.dimension.width / 100 );
		if( this.options.resizable == false && size < this.progressBar.getSize().x )
			size = this.progressBar.getSize().x;
		this.fxTween.start( 'width', [this.progressBar.getSize().x, size] );
	},

	calculate: function( value ) {
		var step = value * 100 / this.options.max;
		return Math.round( step );
	},
	
	setMax: function( value ) {
		this.options.max = value;
		this.apply( this.options.value );
	},
	
	getMax: function() {
		return this.options.max;
	}
} );

Common = new Common;
