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

namespace banco1.domain
{
	/// <summary>
	/// Representa un producto bancario genérico, como una cuenta, una tarjeta, un préstamo, etc.
	/// </summary>
	public abstract class Producto
	{
		protected static String mEntidad="1000";
		protected String mSucursal, mCCC;  // mDC
		protected ArrayList mMovimientos, mTitulares;
		protected bool mActivo;
		protected DateTime mFechaDeCreacion, mFechaDeCancelacion;

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

		public Producto(String s, String ccc, bool activo, DateTime fechaCreacion, DateTime fechaCancel) 
		{
			mSucursal=s;
			mCCC=ccc;
			mActivo=activo;
			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) 
		{
			for (int i=0; i<this.mTitulares.Count; i++) 
			{
				Cliente aux=(Cliente) mTitulares[i];
				if (c.nif.Equals(aux.nif))
					throw new Exception("Ya hay un cliente con ese NIF asignado a esta cuenta");
			}										
			this.mTitulares.Add(c);
		}

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

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

		/******* Otras operaciones ********/
		public abstract bool esCancelable();

		public bool estaActivo() 
		{
			return mActivo;
		}

		public void bloquear() 
		{
			mActivo=false;
		}

		public void desbloquear() 
		{
			mActivo=true;
		}

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

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

		/*** Otras operaciones abstractas ****/
		public abstract void cargaMovimientos(XmlNode nodo);
	}
}
