using System;
using System.Net.Sockets;
using System.Net;

namespace Cajero
{
	public class Banco
	{
		public Socket mYo;
		public IPEndPoint mIP;
		public int mPuerto;
		public bool mFinDeEnvio;
		private IAsyncResult m_asynResult;
		public AsyncCallback pfnCallBack ;

		public Banco(int puerto)
		{
			mPuerto=puerto;
			mIP=new IPEndPoint(IPAddress.Any, mPuerto);
			mYo = new Socket(AddressFamily.InterNetwork,
				SocketType.Stream, ProtocolType.Tcp);
			IPAddress aux=IPAddress.Parse("127.0.0.1");
			EndPoint ipServidor=new IPEndPoint(aux, 1200);
			mYo.Connect(ipServidor);
			mFinDeEnvio = false;
			WaitForData();
		}

		private  void OnDataReceived(IAsyncResult asyn)
		{
			try
			{
				CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;
				//end receive...
				int iRx  = 0 ;
				iRx = theSockId.thisSocket.EndReceive (asyn);
				char[] chars = new char[iRx +  1];
				System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
				int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
				System.String szData = new System.String(chars);
				string aux = szData.ToString();
				if (aux[0].Equals ('#')) mFinDeEnvio = true;
				//madre.recibir(szData.ToString());
				WaitForData();
			}
			catch(Exception se)
			{
				throw se;
			}
		}

		private void WaitForData()
		{
			try
			{
				if (mFinDeEnvio && mPuerto.Equals("8221"))
				{
					this.Cerrar();
				}
				else
				{
					if (mFinDeEnvio) 
					{
						mFinDeEnvio = false;
					}
					if  ( pfnCallBack == null ) 
					{
						pfnCallBack = new AsyncCallback (OnDataReceived);
					}
					CSocketPacket theSocPkt = new CSocketPacket ();
					theSocPkt.thisSocket = mYo;
					// now start to listen for any data...
					m_asynResult = mYo.BeginReceive (theSocPkt.dataBuffer ,0,theSocPkt.dataBuffer.Length ,SocketFlags.None,pfnCallBack,theSocPkt);
				}
			}
			catch(Exception se)
			{
				throw se;
			}
		}		

		public void Enviar (string msg)
		{
			try
			{
				Object objData = msg;
				byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString ());
				mYo.Send (byData);
			}
			catch(Exception se)
			{
				throw se;
			}
		}

		public class CSocketPacket
		{
			public System.Net.Sockets.Socket thisSocket;
			public byte[] dataBuffer = new byte[1];
		}

		public void Cerrar ()
		{
			if ( mYo != null )
			{
				try
				{
					//m_socClient.Shutdown (SocketShutdown.Send);
					mYo.Close ();
					//m_socClient = null;
				}
				catch (Exception ex) 
				{
					throw ex;
				}
			}
		}

	}
}
