/**
 * Global var to indicate the bookingsmodule is used
 * @type {Boolean}
 */
var BookingsModuleAvailable = true;

/**
 * Check for namespace
 */
var BookingsModule = {};

/********************************************************
 * AssetLoader defined in main BookingModule.js file    *
 * for IE6 compatibility (problem with loading order)   *
 ********************************************************/

/**
 * BookingsModule.AssetLoader is responsible for runtime loading of JavaScript assets
 */
BookingsModule.AssetLoader = new Class({
     
	
	Implements: [Events],
	/**
	 * @type {Array}
	 */
	loadedAssets: null,
	
	/**
	 * @type {Array}
	 */
	assetIds: null,	
	
	/**
	 * @type {Array}
	 */
	pendingAssets: null,
	
	/**
	 * @type {Number}
	 */
	assetCounter: 0,
	
	/**
	 * @type {Number}
	 */
	assetChecker: null,
	
	initialize: function() {
		this.loadedAssets = new Array();
		this.pendingAssets = new Array();
		this.assetIds = new Array();
	},
	                                  
	/**
	 * Loads a js file
	 * if onLoaded is passed this method will be called when the asset has been loaded
	 *
	 * @type {String} path
	 * @type {Function} onLoaded
	 */
	loadAsset: function(jsPath, onLoaded) {
		//Check if the requested asset in not already loading or loaded
		if(!this.isAssetLoaded(jsPath)) {
			
			if(!this.isAssetPending(jsPath)) {
				
				//Add jsPath to pending assets
				this.pendingAssets.push(jsPath);
				
				//Create new js asset
				var loadedCall = this.assetDidLoad.pass([jsPath, onLoaded], this);
				this.startCheck();
				
				var head= document.getElementsByTagName('head')[0];
				var script= document.createElement('script');
				script.type= 'text/javascript';

				// For IE
				if(Browser.Engine.trident) {
					script.onreadystatechange = this.ieLoadCheck.bind(this, [script, jsPath, onLoaded])
				} 
				script.onload= this.assetDidLoad.bind(this, [jsPath, onLoaded]);
				script.src= jsPath;
				head.appendChild(script);

			}
			
		} else if($chk(onLoaded)){               
			onLoaded(jsPath);
		}
	},	
	
	startCheck: function() {
		if(this.assetChecker == null) {
			//this.assetChecker = this.checkAssets.periodical(50, this);
		}
	},
	
	ieLoadCheck: function(script, jsPath, methodToDelegate) {
  		if (script.readyState == 'complete' || script.readyState == 'loaded') {
			this.assetDidLoad(jsPath, methodToDelegate);
		} 
	},

	/**
	 * Called by asset.onloaded function.
	 * This method will be called when an asset loaded.
	 * Will trigger the onComplete (if set)
	 *
	 * This is a private method.
	 * @private                    
	 * @param {String} jsPath
	 * @param {Function} methodToDelegate
	 */
	assetDidLoad: function(jsPath, methodToDelegate) {
		//Move jsPath from pending to loaded
		this.pendingAssets.erase(jsPath);
		this.loadedAssets.include(jsPath);

		if($chk(methodToDelegate)) {
			methodToDelegate(jsPath);
		}
	},
	
	/**
	 * Returns a Boolean indicating if a jsPath has been loaded
	 * Will only check for js files loaded through same object instance
	 *
	 * @param {String} jsPath
	 * @return {Boolean}
	 */
	isAssetLoaded: function(jsPath) {
	   return this.loadedAssets.contains(jsPath);
	}, 
	
	/**
	 * Returns a Boolean indicating if a jsPath is pending
	 * Will only check for js files loaded through same object instance
	 *
	 * @param {String} jsPath
	 * @return {Boolean}
	 */	
	isAssetPending: function(jsPath) {
	   return this.pendingAssets.contains(jsPath);
	},

	/**
	 * Returns a Boolean indicating if a jsPath has been requested
	 * Will only check for js files requested through same object instance
	 *
	 * @param {String} jsPath
	 * @return {Boolean}
	 */
	isAssetRequested: function(jsPath) {
		return (this.isAssetPending(jsPath) || this.isAssetLoaded(jsPath));
	}
  
});
//BookingsModule.AssetLoader.implement(new Events);

/**
 * Returns the shared storage object
 * When reading or writing to the storage used the shared object 
 *
 * @return {BookingsModule.Storage}
 */
BookingsModule.SharedAssetLoader = function() {
	
	if(!$chk(BookingsModule.SharedObjects)) {
		BookingsModule.SharedObjects = {};
	}
	if(!$chk(BookingsModule.SharedObjects.AssetLoaderInstance)) {
		BookingsModule.SharedObjects.AssetLoaderInstance = new BookingsModule.AssetLoader();
	}

	return BookingsModule.SharedObjects.AssetLoaderInstance;
}

/********************************************************
 * AssetLoader END                                      *
 ********************************************************/


/**
 * initBookingsModule is the entry point for the bookings module
 *
 * @type {Function}
 */


var MainBookingController = null;
var initBookingsModule = function(targetContainer) {
    // NB: make sure the remote services are available, just check for LabelService if at least that is available
    // and double check targetContainer is present
	
    if ($chk($(targetContainer))) {
        // NB: BookingsModule global namespace is declared in this script, so it's
        // also available for checking online status, which can be changed through assets
        if (BookingsModule.online == true
            && typeof(BookingsModule.ModuleController) != "undefined"
           ) {
            try {
            	
            	 MainBookingController = new BookingsModule.ModuleController(targetContainer);
            } catch(ex) {
            	debug.log(ex)
                
                ShowBookingsModuleOffline('Catch in init BookingsModule');
            }
        } else { // no reason to show offline message if no targetContainer, this means bm not included on purpose
        	
            ShowBookingsModuleOffline('Failed to init BookingsModule');
        }
    }
};

/**
 * some globally used flags
 */

BookingsModule.online = true;

BookingsModule.coreAssets = [
    '/bookingsmodule/js/EurolinesDefines.js',
    '/bookingsmodule/js/utils/JSONResponse.js',
    '/bookingsmodule/js/bm.js',

    '/bookingsmodule/js/assets/BMGeneral.js',
    '/bookingsmodule/js/assets/Storage.js',
    '/bookingsmodule/js/assets/StepController.js',
    '/bookingsmodule/js/assets/FlowController.js',
    '/bookingsmodule/js/assets/Parser.js',
    '/bookingsmodule/js/assets/DictionaryController.js',
    '/bookingsmodule/js/assets/LanguageController.js',
    '/bookingsmodule/js/assets/BookingDetails.js',
    '/bookingsmodule/js/steps_errors.js',

    // NB: can't use constant from EurolinesDefines yet, since it hasn't been loaded yet
    '/bookingsmodule/php-bridge/LabelService.php',

    '/bookingsmodule/php-bridge/js/jsonrpc.js',
    '/bookingsmodule/php-bridge/js/model.js',

    //Site Specific settings
    '/bookingsmodule/php-bridge/Config.js.php',

    //Load main controller file
    '/bookingsmodule/js/assets/ModuleController.js',
    //Load main controller file
    '/bookingsmodule/js/assets/RequestValueParser.js'];

/**
 * The function to be handled on domReady, for really loading the bookingmodule
 */
BookingsModule.domReady = false;
BookingsModule.domReadyCall = function() {
	
	  BookingsModule.domReady	= true;

    // NB: load JS assets on domready, for IE compatibility,
    // using the already included (Shared)AssetLoader, handling IE correctly
    // NB2: iff bookingsModule div element is defined, otherwise bm wasn't include anyway
	  
    if ($chk($('bookingsModule'))) {
        BookingsModule.coreAssetLoadedCount = 0;
        BookingsModule.coreAssets.each(
            BookingsModule.loadJSAsset.bind(BookingsModule)
            
        );
        // and add hot-key for getting bookingid
        window.onkeypress = alertBookingId;
    }
};


BookingsModule.loadJSAsset = function(jsPath) {
	
    BookingsModule.SharedAssetLoader().loadAsset(jsPath, BookingsModule.loadedAsset.bind(BookingsModule));
    
};

BookingsModule.loadedAsset = function() {
	
	  if(++BookingsModule.coreAssetLoadedCount == BookingsModule.coreAssets.length) {
		    initBookingsModule('bookingsModule');
	  }
};

alertBookingId = function(e) {
    var evt = new Event(e);

    // Ctrl + Alt + D -> charcode 240
    if (evt.event.charCode == '240') {
        alert("id: " + MainBookingController.getBookingId());
    }
}

/**
 * the domready call needs to be added
 */
window.addEvent('domready', BookingsModule.domReadyCall.bind(window));
