using System;
using System.Data.OleDb;
using System.Data.SqlClient;
using banco1.persistencia;

namespace banco1.domain
{
	/// <summary>
	/// Descripción breve de Tarjeta.
	/// </summary>
	public abstract class Tarjeta : Producto
	{
		protected String mNumero;
		protected String mTitular;
		protected byte mMesCaducidad, mAñoCaducidad;
		protected double mCredito;
		protected Cuenta mCuentaAsociada;

		public Tarjeta() : base()
		{
		}

		public Tarjeta(String sucursal, String ccc) : base(sucursal, ccc)
		{
			String SQL="Select Número, Titular, MesCaducidad, AñoCaducidad, " +
				"Crédito, SucursalCuentaAsociada, CCCCuentaAsociada " +
				"from Tarjetas where Sucursal=? and CCC=?";
			OleDbCommand cmd=Broker.getCommand(SQL);
			cmd.Parameters.Add("", OleDbType.VarChar).Value=sucursal;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=ccc;
			OleDbDataReader r=cmd.ExecuteReader();
			if (r.Read()) 
			{
				this.mSucursal=sucursal;
				this.mCCC=ccc;
				this.mNumero=r.GetString(0);
				this.mTitular=r.GetString(1);
				this.mMesCaducidad=r.GetByte(2);
				this.mAñoCaducidad=r.GetByte(3);
				this.mCredito=r.GetDouble(4);
				this.mCuentaAsociada=new Cuenta(r.GetString(5), r.GetString(6));
			}
		}

		public Tarjeta(Cuenta cuentaAsociada) : base(cuentaAsociada.sucursal)
		{
			this.mCuentaAsociada=cuentaAsociada;
			this.mNumero=this.getNumeroSiguiente();
			this.mMesCaducidad=(byte) DateTime.Now.Month;
			this.mAñoCaducidad=(byte) (DateTime.Now.Year+3);
			actualizaNumeroSiguiente(this.mNumero);
		}

		protected String getNumeroSiguiente() 
		{
			String SQL="Select Ultimo from UltimoNumeroDeTarjeta";
			OleDbCommand cmd=Broker.getCommand(SQL);
			OleDbDataReader r=cmd.ExecuteReader();
			if (r.Read()) 
			{
				String ultimo=r.GetString(0);
				double dUltimo=double.Parse(ultimo)+1;
				ultimo=""+dUltimo;
				int longitud=ultimo.Length;
				for (int i=0; i<16-longitud; i++)
					ultimo="0" + ultimo;
				cmd.Connection.Close();
				return ultimo;
			} 
			else throw new Exception("Error en Tarjeta::getNumeroSiguiente()");
		}

		protected void actualizaNumeroSiguiente(String ultimo) 
		{
			String SQL="Update UltimoNumeroDeTarjeta set Ultimo=?";
			OleDbCommand cmd=Broker.getCommand(SQL);
			cmd.Parameters.Add("", OleDbType.VarChar).Value=ultimo;
			cmd.ExecuteNonQuery();
			cmd.Connection.Close();
		}

		public override bool esCancelable() 
		{
			return true;
		}

		public void setTitular(Cliente c) 
		{
			this.mCuentaAsociada.cargaTitulares();
			bool encontrado=false;
			foreach (Cliente t in this.mCuentaAsociada.titulares)
				if (t.nif.Equals(c.nif)) 
					encontrado=true;
			if (!encontrado)
				throw new Exception("El titular de la tarjeta debe ser " +
					"uno de los titulares de la cuenta asociada");
			String titular=c.nombre + " " + c.apellidos;
			if (titular.Length<=20)
				mTitular=titular;
			else 
				mTitular=titular.Substring(0, 20);
		}

		public String getTitular() 
		{
			return mTitular;
		}

		public String numeroDeTarjeta 
		{
			get { return this.mNumero; }
			set { this.mNumero=value; }
		}

		public abstract void sacarDinero(double importe);
		public abstract void pagarEnComercio(double importe, String comercio);
	}
}
