using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.IO;
using System.Data;

namespace MultiUser.Web
{
	/// <summary>
	/// Summary description for DataService
	/// </summary>
	[WebService(Namespace = "http://tempuri.org/")]
	[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
	[System.ComponentModel.ToolboxItem(false)]
	// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
	// [System.Web.Script.Services.ScriptService]
	public class DataService : System.Web.Services.WebService
	{

		[WebMethod]
		public byte[] GetData(string tables)
		{
			// Create DataSet with connection string
			var ds = GetDataSet();

			// Load data into DataSet
			ds.Fill(tables.Split(','));

			// Persist to stream
			var ms = new System.IO.MemoryStream();
			ds.WriteXml(ms, XmlWriteMode.WriteSchema);

			// Return stream data
			return ms.ToArray();
		}

		[WebMethod]
		public string UpdateData(byte[] dtAdded, byte[] dtModified, byte[] dtDeleted)
		{
			try
			{
				UpdateData(dtAdded, DataRowState.Added);
				UpdateData(dtModified, DataRowState.Modified);
				UpdateData(dtDeleted, DataRowState.Deleted);
				return null;
			}
			catch (Exception x)
			{
				return x.Message;
			}
		}

		void UpdateData(byte[] data, DataRowState state)
		{
			// No changes, no work
			if (data == null)
			{
				return;
			}

			// Load data into dataset
			var ds = GetDataSet();
			var ms = new MemoryStream(data);
			ds.ReadXml(ms);
			ds.AcceptChanges();

			// Update row states with changes
			foreach (DataTable dt in ds.Tables)
			{
				foreach (DataRow dr in dt.Rows)
				{
					switch (state)
					{
						case DataRowState.Added:
							dr.SetAdded();
							break;
						case DataRowState.Modified:
							dr.SetModified();
							break;
						case DataRowState.Deleted:
							dr.Delete();
							break;
					}
				}
			}

			// Update the database
			ds.Update();
		}

		SmartDataSet GetDataSet()
		{
			// Get physical location of the mdb file
			string mdb = Path.Combine(
			  Context.Request.PhysicalApplicationPath, @"App_Data\Nwind.mdb");

			// Check that the file exists
			if (!File.Exists(mdb))
			{
				string msg = string.Format("Cannot find database file {0}.", mdb);
				throw new FileNotFoundException(msg);
			}

			// Make sure file is not read-only (source control often does this...)
			FileAttributes att = File.GetAttributes(mdb);
			if ((att & FileAttributes.ReadOnly) != 0)
			{
				att &= ~FileAttributes.ReadOnly;
				File.SetAttributes(mdb, att);
			}

			// Create and initialize the SmartDataSet
			var dataSet = new SmartDataSet();
			dataSet.ConnectionString =
			  "provider=microsoft.jet.oledb.4.0;data source=" + mdb;

			// sample connection string for SQL Server Express (replace Initial Catalog value by the valid catalog name)
			// dataSet.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=test;Data Source=.\\SQLEXPRESS";
			return dataSet;
		}
	}
}
