using System;
using System.Data;
using DotNetMock;

namespace DotNetMock.Framework.Data
{
	/// <summary>
	/// Mock Object representing a System.Data.DataSet.
	/// </summary>
	public class MockDataSet : DataSet, IMockObject
	{
		/// <summary>
		/// Name of this mock <see cref="DataSet"/>.
		/// Defaults to 'MockDataSet'.
		/// </summary>
		protected string name = "";
		/// <summary>
		/// Stores whether this object has been verified yet.
		/// Defaults to false.
		/// </summary>
		protected bool verified = false;

		/// <summary>
		/// Creates a mock <see cref="DataSet"/>.
		/// </summary>
		public MockDataSet() {
			this.name = "MockDataSet";
		}
		/// <summary>
		/// Sets the rows that will be returned by the first
		/// <see cref="DataTable"/> in this <see cref="DataSet"/>.
		/// </summary>
		/// <param name="data">n x m array of data representing
		/// a <see cref="DataTable"/> in this <see cref="DataSet"/></param>
		public void SetRows( object[,] data )
		{
			DataTable dataTable = new DataTable();
			DataColumn column = null;

			for(int i=0; i<data.GetLength( 1 ); i++)
			{
				column = new DataColumn();
				column.DataType = typeof(object);
				dataTable.Columns.Add( column );
			}

			for(int i=0; i<data.GetLength( 0 ); i++)
			{
				dataTable.Rows.Add( getRow( data, i ) );
			}
			this.Tables.Clear();
			this.Tables.Add( dataTable );
		}

		private object[] getRow( object[,] data, int rowIndex )
		{
			int columnCount = data.GetLength( 1 );

			object[] newRow = new object[columnCount];

			for(int i=0; i<columnCount; i++)
			{
				newRow[i] = data[rowIndex, i];
			}
			return newRow;
		}


		#region Implementation of IMockObject
		/// <summary>
		/// <see cref="IMockObject.NotImplemented"/>
		/// </summary>
		/// <param name="methodName">name of method not implemented</param>
		public void NotImplemented(string methodName)
		{
			throw new NotImplementedException( methodName + " is currently not implemented." );		
		}
		/// <summary>
		/// Name of this mock object.
		/// </summary>
		public string MockName
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}
		/// <summary>
		/// Whether this mock object has been verified.
		/// <see cref="Verify"/>
		/// </summary>
		public bool IsVerified
		{
			get { return verified; }
		}
		#endregion

		#region Implementation of IVerifiable
		/// <summary>
		/// <see cref="IVerifiable.Verify"/>
		/// </summary>
		public void Verify()
		{
			Verifier.Verify( this );
			verified = true;
		}
		#endregion
	}
}
