
package com.natejc.utils.communication
{
	import flash.net.XMLSocket;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.DataEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	

// **********************************************************************************
// **********************************************************************************


	/**
	 * Establishes a connection with another application via the XMLSocket class over TCP/IP.
	 * 
	 * @author	Nate Chatellier
	 */
	public class ConnectionEstablisher
	{
		
	// USER DEFINED CONSTANTS
		protected static const DEFAULT_IP:String = "127.0.0.1";
		protected static const DEFAULT_PORT:int = 5525;
		
		
	// MEMBER VARIABLES
		protected var _xmlSocket:XMLSocket;		// the XML Socket server object, used to send & receive messages
		protected var _sIPAddress:String;		// the IP address where the server is located (TCP/IP)
		protected var _nPortNumber:uint;		// the port number that the server & client will be using (TCP/IP)
		
		
	// **********************************************************************************


		/**
		 * Creates a new instance of the ConnectionEstablisher class, configures all applicable
		 * XMLSocket event listeners, and connects to the specified IP address through the specified port.
		 *
		 * @param sIPAddress	The IP address of the computer in-which a connection is to be established.
		 * @param nPortNumber	The port number of the application in-which a connection is to be established.
		 */
		function ConnectionEstablisher(sIPAddress:String = DEFAULT_IP, nPortNumber:int = DEFAULT_PORT)
		{
			_xmlSocket = new XMLSocket();
			configureSocketListeners(_xmlSocket);
			
			establishConnection(sIPAddress, nPortNumber);
			
		} // END CONSTRUCTOR
	
	
	// **********************************************************************************
	
	
		/**
		 * Establishes an XMLSocket connection with the server at <code>sIPAddress</code> over port <code>nPortNumber</code>.
		 *
		 * @param sIPAddress	The IP address of the computer in-which a connection is to be established (or "" to use the previously assigned IP)
		 * @param nPortNumber	The port number of the application in-which a connection is to be established (or -1 to use the previously assigned port number)
		 */
		public function establishConnection(sIPAddress:String = "", nPortNumber:int = -1):void
		{
			if (sIPAddress != "") _sIPAddress = sIPAddress;
			if (nPortNumber > 0) _nPortNumber = nPortNumber;
			
			trace("\n\nAttempting to connect to "+_sIPAddress+" on port "+_nPortNumber+"...");
				
			_xmlSocket.connect(_sIPAddress, _nPortNumber);

		} // END FUNCTION establishConnection


	// **********************************************************************************

		
		/**
		 * Sends data through the XMLSocket object _xmlSocket.
		 * Prerequisite: _xmlSocket must have been properly initialized and connected.
		 *
		 * @param data The data that should be sent through the XMLSocket.
		 */
        public function send(data:Object):void
		{
			try
			{
				_xmlSocket.send(data);
			}
			catch(e:Error)
			{
				trace("*** WARNING in ConnectionEstablisher.send() --> the socket is not currently connected");
			} // END TRY
        } // END FUNCTION send

		
	// **********************************************************************************

		
		/**
		 * Initializes all of the event listeners for the IEventDispatcher object (e.g. an XMLSocket object).
		 *
		 * @param dispatcher The IEventDispatcher object (e.g. an XMLSocket object) that should listen to the events.
		 */
        protected function configureSocketListeners(dispatcher:IEventDispatcher):void
		{
            dispatcher.addEventListener(Event.CLOSE,						closeHandler);
            dispatcher.addEventListener(Event.CONNECT,						connectHandler);
            dispatcher.addEventListener(DataEvent.DATA,						dataHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR,				ioErrorHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS,				progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR,	securityErrorHandler);
        } // END FUNCTION configureSocketListeners

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of an Event.CLOSE event generated by the XMLSocket.
		 *
		 * @param event The generated Event.CLOSE event.
		 */
        protected function closeHandler(event:Event):void
		{
			trace("*** ConnectionEstablisher.closeHandler() -> the socket has been closed: " + event);

        } // END FUNCTION closeHandler

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of an Event.CONNECT event generated by the XMLSocket.
		 *
		 * @param event The generated Event.CONNECT event.
		 */
        protected function connectHandler(event:Event):void
		{
			trace("ConnectionEstablisher.connectHandler() -> Successfully connected to "+_sIPAddress+" on port "+_nPortNumber+"\n > "+event+"\n");

        } // END FUNCTION connectHandler

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of a DataEvent.DATA event generated by the XMLSocket.
		 *
		 * @param event The generated DataEvent.DATA event.
		 */
        protected function dataHandler(event:DataEvent):void
		{
			trace("ConnectionEstablisher.dataHandler: " + event);

        } // END FUNCTION dataHandler

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of an IOErrorEvent.IO_ERROR event generated by the XMLSocket.
		 *
		 * @param event The generated IOErrorEvent.IO_ERROR event.
		 */
        protected function ioErrorHandler(event:IOErrorEvent):void
		{
			trace("ConnectionEstablisher.ioErrorHandler: " + event);

        } // END FUNCTION ioErrorHandler

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of an ProgressEvent.PROGRESS event generated by the XMLSocket.
		 *
		 * @param event The generated ProgressEvent.PROGRESS event.
		 */
        protected function progressHandler(event:ProgressEvent):void
		{
			trace("ConnectionEstablisher.progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);

        } // END FUNCTION progressHandler

		
	// **********************************************************************************

		
		/**
		 * Handles the occurence of an SecurityErrorEvent.SECURITY_ERROR event generated by the XMLSocket.
		 *
		 * @param event The generated SecurityErrorEvent.SECURITY_ERROR event.
		 */
        protected function securityErrorHandler(event:SecurityErrorEvent):void
		{
			trace("ConnectionEstablisher.securityErrorHandler: " + event);

        } // END FUNCTION securityErrorHandler


// **********************************************************************************
// **********************************************************************************


	} // END CLASS ConnectionEstablisher
} // END PACKAGE

