#region Copyright and GPL
/*************************************************************************
 * dataMagus - The open source database learning software
 * Copyright (C) 2007 by all authors
 * Authors: Monika Schwitter (monsy@gmx.ch)
 *          Jürg Zgraggen (j.zgraggen@ejaz.net)
 *          HSLU (Hochschule Luzern - Technik+Architektur)
 * 
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *************************************************************************/
#endregion
#region Using
using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using dataMagus.Common.Physical.Relational;
using dataMagus.Common.PlugIn.Generator;
using dataMagus.Common.Physical;
using dataMagus.Common;
#endregion

namespace dataMagus.Forms.Elements
{
	/// <summary>
	/// Datatype form for managing the base and custom types on the schema.
	/// </summary>
	public partial class DataTypeForm : Form
	{
        #region Members
        /// <summary>
        /// Schema data the form is based on.
        /// </summary>
        private ISchema _schema = null;
        
        /// <summary>
        /// Dataview for the base datatypes used in the grid.
        /// </summary>
        private DataView _baseView = null;
        
        /// <summary>
        /// Dataview for the custom datatypes used in the grid.
        /// </summary>
        private DataView _customView = null;
        #endregion

        #region Constructors / Destructors
        /// <summary>
        /// Default constructor.
        /// </summary>
        public DataTypeForm()
		{
			InitializeComponent();
        }
        #endregion

        #region Properties
        /// <summary>
        /// Schema data the form is based on.
        /// </summary>
        public ISchema Schema
        {
            set { this._schema = value; }
        }
        #endregion

        #region Methodes
        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
        private void applyButton_Click(object sender, EventArgs e)
        {
            try
            {
                this.Save();
            }
            catch (Exception ex)
            {
                MessageForm.ShowDialog(ex);
            }
        }

        private void Save()
        {
            if (!this.FormIsValidate())
            {
                return;
            }

            DataView dv = (DataView)customTypesDataGridView.DataSource;

            DataTable modifiedTable = dv.Table.GetChanges();
            if (null != modifiedTable)
            {
                foreach (DataRow row in modifiedTable.Rows)
                {
                    if (DataRowState.Added == row.RowState)
                    {
                        DataType dataType = DataType.CreateDataType((DataType.BaseDataType)Enum.Parse(typeof(DataType.BaseDataType),
                            row["BaseType"].ToString()),
                            row["Name"].ToString());
                        DataContainer.Instance.PhysicalData.AddDataType(dataType);
                    }
                    else if (DataRowState.Modified == row.RowState)
                    {
                        DataType originalDataType = DataType.CreateDataType((DataType.BaseDataType)Enum.Parse(typeof(DataType.BaseDataType),
                            row["BaseType", DataRowVersion.Original].ToString()),
                            row["Name", DataRowVersion.Original].ToString());
                        DataType dataType = DataType.CreateDataType((DataType.BaseDataType)Enum.Parse(typeof(DataType.BaseDataType),
                            row["BaseType"].ToString()),
                            row["Name"].ToString());
                        DataContainer.Instance.PhysicalData.ModifyDataType(dataType, originalDataType);
                    }
                    else if (DataRowState.Deleted == row.RowState)
                    {
                        DataType dataType = DataType.CreateDataType((DataType.BaseDataType)Enum.Parse(typeof(DataType.BaseDataType),
                            row["BaseType", DataRowVersion.Original].ToString()),
                            row["Name", DataRowVersion.Original].ToString());
                        DataContainer.Instance.PhysicalData.RemoveDataType(dataType);
                    }
                }
                dv.Table.AcceptChanges();
            }
        }

        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
        private void OkButtonClick(object sender, EventArgs e)
		{
        	try
			{
                this.Save();
	            this.DialogResult = DialogResult.OK;
	            this.Close();
			}
			catch (Exception ex)
			{
				MessageForm.ShowDialog(ex);
			}
		}
		
        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
		private void CancelButtonClick(object sender, EventArgs e)
		{
			try
			{
	            this.DialogResult = DialogResult.Cancel;
	            this.Close();
			}
			catch (Exception ex)
			{
				MessageForm.ShowDialog(ex);
			}
		}

		/// <summary>
		/// Validate the data on the form and set the specified error provider for the
		/// invalide control.
		/// </summary>
		/// <returns>
		/// true indicates that the form is valid, false indicates that the form
		/// contains invalid data which sould not be used until corrected.
		/// </returns>
        private bool FormIsValidate()
        {
            bool isValid = true;
            return isValid;
        }

        /// <summary>
        /// Create dataview for the base datatypes.
        /// </summary>
        /// <returns>Dataview to be used in the grid.</returns>
        private DataView CreateBaseData()
        { 
            // fill base types mapping
            DataTypeDataSet dsx = new DataTypeDataSet();
            IEnumerator datatypesEnumerator = DataContainer.Instance.PhysicalData.GetDataTypes();
            while (datatypesEnumerator.MoveNext())
            {
                DataType datatype = (DataType)datatypesEnumerator.Current;
                if (!datatype.IsDerived)
                {
                    dsx.DataTypeDataTable.AddDataTypeDataTableRow(datatype.Name, datatype.BaseType.ToString());
                }
            }
            dsx.AcceptChanges();
            return dsx.DataTypeDataTable.DefaultView;
        }

        /// <summary>
        /// Create dataview for the custom datatypes.
        /// </summary>
        /// <returns>Dataview to be used in the grid.</returns>
        private DataView CreateCustomData()
        {
            // fill custom types mapping
            DataTypeDataSet dsx = new DataTypeDataSet();
            IEnumerator datatypesEnumerator = DataContainer.Instance.PhysicalData.GetDataTypes();
            while (datatypesEnumerator.MoveNext())
            {
                DataType datatype = (DataType)datatypesEnumerator.Current;
                if (datatype.IsDerived)
                {
                    dsx.DataTypeDataTable.AddDataTypeDataTableRow(datatype.Name, datatype.BaseType.ToString());
                }
            }
            dsx.AcceptChanges();
            return dsx.DataTypeDataTable.DefaultView;
        }

        /// <summary>
		/// Load the data into the form.
		/// </summary>
        private void LoadData()
        {
            // fill generators
            List<IGenerator> generators = GeneratorManager.Instance.FindInterfaceTypeForSchema(this._schema);
            this.generatorCombo.DisplayMember = "Name";
            this.generatorCombo.DataSource = generators;
        }

        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
        private void DataTypeForm_Load(object sender, EventArgs e)
        {
        	try
			{
                this._baseView = this.CreateBaseData();
                this.dataTypesDataGridView.DataSource = this._baseView;


                DataView baseViewDropDown = this.CreateBaseData();
                this.customTypesDataGridView.AutoGenerateColumns = false;
                this.customTypesDataGridView.DataMember = "ColumnMappingsDataTable";

                nameColumn.DataPropertyName = "Name";
                baseTypeDropDownColumn.DataPropertyName = "BaseType";
                baseTypeDropDownColumn.DisplayMember = "BaseType";
                baseTypeDropDownColumn.ValueMember = "BaseType";
                baseTypeDropDownColumn.DataSource = baseViewDropDown;

                this._customView = this.CreateCustomData();
                this.customTypesDataGridView.DataSource = this._customView;

                this.LoadData();

			}
			catch (Exception ex)
			{
				MessageForm.ShowDialog(ex);
			}
        }

        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
        private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.tabControl.SelectedTab == this.targetTab)
                {
                    this.generatorCombo_SelectedIndexChanged(sender, e);
                }
            }
            catch (Exception ex)
            {
                MessageForm.ShowDialog(ex);
            }
        }

        /// <summary>
        /// Event handler.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="e">EventArgs</param>
        private void generatorCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                this.generatorPanel.Controls.Clear();
                if (-1 != this.generatorCombo.SelectedIndex)
                {
                    IGenerator generator = (IGenerator)this.generatorCombo.SelectedItem;
                    GeneratorControl ctrl = generator.GetGeneratorDataTypeMappingsControl();
                    if (null != ctrl)
                    {
                        ctrl.Dock = DockStyle.Fill;
                        this.generatorPanel.Controls.Add(ctrl);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageForm.ShowDialog(ex);
            }
        }
        #endregion
    }
}
