using System;
using System.Collections;
using System.Xml;

namespace banco1.domain
{
	/// <summary>
	/// Representa una cuenta corriente
	/// </summary>
	public class Cuenta
	{
		protected static String mEntidad="1000";
		protected String mSucursal, mCCC;  // mDC
		protected ArrayList mMovimientos, mTitulares;
		protected bool mActiva;
		protected DateTime mFechaDeCreacion, mFechaDeCancelacion;

		public Cuenta(String s, String ccc)
		{
			mSucursal=s;
			mCCC=ccc;
			mFechaDeCreacion=System.DateTime.Now;
			mMovimientos=new ArrayList();
			mTitulares=new ArrayList();
		}

		public Cuenta(String s, String ccc, bool activa, DateTime fechaCreacion, DateTime fechaCancel)
		{
			mSucursal=s;
			mCCC=ccc;
			mActiva=activa;
			mFechaDeCreacion=fechaCreacion;
			mFechaDeCancelacion=fechaCancel;
			mMovimientos=new ArrayList();
			mTitulares=new ArrayList();
		}

		public static String entidad 
		{
			get { return mEntidad; }
		}

		public String sucursal
		{
			get { return mSucursal; }
		}

		public String ccc 
		{
			get { return mCCC; }
		}

		public String digitoDeControl
		{
			get 
			{ 
				return getDigitoDeControl(mSucursal, mCCC);
			}
		}

		public String numero 
		{
			get { return Cuenta.entidad + this.sucursal + this.digitoDeControl + this.ccc; }
		}

		public static String getDigitoDeControl(String sucursal, String ccc) 
		{
			if (sucursal.Equals("")) sucursal="0";
			if (ccc.Equals("")) ccc="0";
			int e=int.Parse(mEntidad);
			int s=int.Parse(sucursal);
			int iccc=int.Parse(ccc);
			int dc=(e+s+iccc) % 25;
			String result=""+dc;
			if (result.Length==1) 
				result="0" + result;
			return result;
		}        

		public void add(Cliente c) 
		{
			this.mTitulares.Add(c);
		}

		public ArrayList titulares 
		{
			get { return this.mTitulares; }
		}

		public ArrayList movimientos 
		{
			get { return this.mMovimientos; }
		}

		public void cargaMovimientos(XmlNode nodoCuenta) 
		{
			if (nodoCuenta.ChildNodes.Count==1) 
				return;
			XmlNode movimientos=nodoCuenta.ChildNodes[1];
			for (int i=0; i<movimientos.ChildNodes.Count; i++) 
			{
				XmlNode nodoMovimiento=movimientos.ChildNodes[i];
				String concepto=nodoMovimiento.Attributes["concepto"].Value;
				DateTime fecha=DateTime.Parse(nodoMovimiento.Attributes["fecha"].Value);
				double importe=double.Parse(nodoMovimiento.Attributes["importe"].Value);
				Movimiento m=new Movimiento(concepto, fecha, importe);
				this.mMovimientos.Add(m);
			}
		}

		/*** Operaciones con dinero ****/
		public double saldo 
		{
			get { 
				double result=0;
				for (int i=0; i<this.mMovimientos.Count; i++) 
				{
					Movimiento m=(Movimiento) this.mMovimientos[i];
					result+=m.importe;
				}
				return result;
			}
		}

		public void ingresar(double importe) 
		{
			Movimiento m=new Movimiento("Ingreso en efectivo", System.DateTime.Now, importe);
			this.mMovimientos.Add(m);
		}

		public void retirar(double importe) 
		{
			importe=-importe;
			Movimiento m=new Movimiento("Retirada de efectivo", System.DateTime.Now, importe);
			this.mMovimientos.Add(m);
		}

		public void transferir(Cuenta destino, double importe) 
		{
			Movimiento m=new Movimiento("Orden de transferencia", System.DateTime.Now, -importe);
			this.mMovimientos.Add(m);
			Movimiento m2=new Movimiento("Transferencia a su favor", DateTime.Now, importe);
			destino.mMovimientos.Add(m2);
		}

		public void reciboDomiciliado(String organismo, double importe) 
		{
			Movimiento m=new Movimiento("Recibo de " + organismo, System.DateTime.Now, -importe);
			this.mMovimientos.Add(m);
		}


		/******* Otras operaciones ********/
		public bool esCancelable() 
		{
			if (saldo<0 || !mActiva) return false;
			return true;
		}

		public bool estaActiva() 
		{
			return mActiva;
		}

		public void bloquear() 
		{
			mActiva=false;
		}

		public void desbloquear() 
		{
			mActiva=true;
		}

		public void cancelar() 
		{
			this.mFechaDeCancelacion=System.DateTime.Now;
		}

		public bool cancelada 
		{
			get { return !mFechaDeCancelacion.Equals(DateTime.MinValue); }
		}
	}
}
