/**
 * Calls controller
 * 
 * @author Pierre HUBERT
 */

ComunicWeb.components.calls.controller = {

	/**
	 * This variable contains the initialization state
	 * of the call component
	 */
	_is_init: false,

	/**
	 * This variable contains whether the user is being
	 * notified of a call or not
	 */
	_is_processing_call: false,

	/**
	 * Initialize calls component
	 */
	init: function(){
	
		//We init this component just once
		if(this._is_init)
			return;

		ComunicWeb.debug.logMessage("Initialize calls component");

		//Initialize call container
		var initializeCallContainer = function(){

			//Signed out users can not make calls
			if(!signed_in()){
				ComunicWeb.components.calls.controller.userSignedOut();
				return;
			}

			//Need a wrapper to continue
			if(!byId("wrapper"))
				return;

			//Check if calls target already exists
			if(byId("callsTarget"))
				return;
			
			//Call system must be available
			if(!ComunicWeb.components.calls.controller.isAvailable())
				return;
				
			//Create call target
			createElem2({
				appendTo: byId("wrapper"),
				type: "div",
				id: "callsTarget"
			});

			//Now we have to reopen current calls
			ComunicWeb.components.calls.controller.reopenCurrentCalls();
		}

		//We wait the user to be connected before trying to get
		// call configuration
		document.addEventListener("got_user_id", function(){

			//Check if we have already the call configuration
			if(ComunicWeb.components.calls.__config !== undefined)
				return;
			
			ComunicWeb.components.calls.interface.getConfig(function(config){

				//Check if we could not get calls configuration
				if(config.error)
					return;

				//Save calls configuration
				ComunicWeb.components.calls.__config = config;

				initializeCallContainer();
			});

		});

		// Each time a page is opened, wec check if we have to create calls target
		document.addEventListener("openPage", function(){
			initializeCallContainer();
		});
	},

	/**
	 * Access calls configuration
	 * 
	 * @return Cached calls configuration
	 */
	getConfig: function() {
		return ComunicWeb.components.calls.__config;
	},

	/**
	 * Check if the call feature is available or not
	 */
	isAvailable: function(){

		//First, check if this browser support webrtc
		if(!SimplePeer.WEBRTC_SUPPORT)
			return false;

		//If do not have any call configuration, it is not possible to
		//make calls
		if(this.getConfig() == null)
			return false;

		//Read configuration
		return this.getConfig().enabled;
	},

	/**
	 * Initiate a call for a conversation
	 * 
	 * @param {Number} conversationID The ID of the target conversation
	 */
	call: function(conversationID){
		
		//Create / Get call information for the conversation
		ComunicWeb.components.calls.interface.createForConversation(conversationID, function(call){

			if(call.error)
				return notify("Could not get a call for this conversation!", "danger");
			
			ComunicWeb.components.calls.controller.open(call);

		});

	},

	/**
	 * Call this method to initialize a call for a call we have information about
	 * 
	 * @param {Object} call Information about the call
	 */
	open: function(call){

		//Add the call to the list of opened calls
		ComunicWeb.components.calls.currentList.addCallToList(call.id);

		//Initialize call
		ComunicWeb.components.calls.callWindow.initCall(call);
	},

	/**
	 * This method is called each time the notification service
	 * detect that the number of pending calls has increased. It
	 * must in fact be "thread-safe" to avoid to do twice things
	 * that should be one only once
	 * 
	 * @param {number} number The number of pending calls
	 */
	newCallsAvailable: function(number){

		//Check if user is already processing a call
		if(this._is_processing_call)
			return;
		this._is_processing_call = true;
		
		/**
		 * Switch processing call to false
		 */
		var undoIsProcessing = function(){
			ComunicWeb.components.calls.controller._is_processing_call = false;
		}

		//Get information about the next pending call
		ComunicWeb.components.calls.interface.getNextPendingCall(function(call){
			
			//Check if there is no pending call
			if(call.notice)
				return undoIsProcessing();
			
			ComunicWeb.components.conversations.utils.getNameForID(call.conversation_id, function(name){

				//Check for errors
				if(!name){
					ComunicWeb.debug.logMessage("Could not get the name of the conversation for a call, cannot process it!");
					undoIsProcessing();
					return;
				}

				//Show ring screen
				var prompting = true;
				var ringScreenInfo = ComunicWeb.components.calls.ringScreen.show(name, 30, function(accept){
					
					prompting = false;

					undoIsProcessing();

					ComunicWeb.components.calls.controller.applyReponseForCall(call, accept);

				});

				//Regulary check if the call is still valid
				var interval = setInterval(function(){

					if(!prompting)
						return clearInterval(interval);

					ComunicWeb.components.calls.interface.getInfo(call.id, function(info){

						//Check for errors
						if(info.error)
							return;

						//Refuse the call if everyone has left it
						if(ComunicWeb.components.calls.utils.hasEveryoneLeft(info))
						ringScreenInfo.respond(false);
					});
				}, 2000);


			});

		});
	},

	/**
	 * Apply a response for the call
	 * 
	 * @param {Object} call Information about the target call
	 * @param {Boolean} accept TRUE to accept call / FALSE else
	 */
	applyReponseForCall: function(call, accept){

		//Send response to server
		ComunicWeb.components.calls.interface.respondToCall(call.id, accept, function(r){

			//Check for error
			if(r.error)
				return notify("Could not send response to call to server!", "danger");

			if(!accept)
				return;
			
			//We may start the call now
			ComunicWeb.components.calls.controller.open(call);

		});

	},

	/**
	 * Reopen all current calls
	 */
	reopenCurrentCalls: function(){

		//Process each call to open it
		ComunicWeb.components.calls.currentList.getCurrentCallsList().forEach(function(entry){
			
			ComunicWeb.components.calls.interface.getInfo(entry, function(call){

				if(call.error){
					ComunicWeb.components.calls.currentList.removeCallFromList(entry);
					return notify("Could not get information about a call!", "danger");
				}
				
				ComunicWeb.components.calls.controller.open(call);

			});

		});

	},

	/**
	 * Call this method only if the system is sure that
	 * nobody is signed in the current tab
	 */
	userSignedOut: function(){
		
		//Remove all the current calls from the list
		ComunicWeb.components.calls.currentList.removeAllCalls();

	}
}