using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

//========================================================DataTypes
#region Data Types
//-----------------------
public enum DBOperation
{
    Select, Insert, Update, Delete, StoredProcedure
}
//-----------------------
public enum Operatotrs
{
    کوچکتر, کوچکتر_مساوی, مساوی, بزرگتر, بزرگتر_مساوی
}
//-----------------------
public enum Concat_Type
{
    And, Or, None
}
//-----------------------
public struct Conditions
{
    internal String FieldName;
    internal Operatotrs Operator;
    internal Object Value;
    internal Concat_Type Concat;
}
//-----------------------
#endregion
//========================================================Condition Class
#region Condition Class
public class Condition
{
    #region Variables
    private Conditions[] Condition_Value;
    private Int16 Tedad_Item;
    //------------
    /// <param name="Lenght">
    /// .تعداد شرط هایی که می خواهید اعمال کنید
    /// </param>
    public Condition(Int16 Lenght)
    {
        Condition_Value = new Conditions[Lenght];
        Tedad_Item = 0;
    }
    #endregion
    //------------
    #region XML
    /// <summary>
    /// .این متد، شرط های مختلف را روی عملیات شما اعمال می کند
    /// </summary>
    /// <param name="FieldName">
    /// .نام فیلدی که می خواهید شرط را روی آن اعمال کنید
    /// </param>
    /// <param name="Operator">
    /// نوع عملیات مقایسه ای
    /// </param>
    /// <param name="Value">
    /// مقدار برای انجام عمل مقایسه
    /// </param>
    /// <param name="Concat">
    /// را وارد نمایید None نحوه اتصال این فیلد به فیلد دیگر. برای آخرین فیلد، نوع
    /// </param>
    #endregion
    #region AddCondition1
    public void AddCondition(String FieldName, Operatotrs Operator, Object Value, Concat_Type Concat)
    {
        if (Tedad_Item > Condition_Value.Length - 1)
            throw new Exception("تعداد شرط وارد شده، بیش از تعداد تعیین شده است");
        //-------------------------
        if (Tedad_Item == Condition_Value.Length - 1)
            Concat = Concat_Type.None;
        //-------------------------
        if (Tedad_Item > 0)
            if (Condition_Value[Tedad_Item - 1].Concat == Concat_Type.None)
                throw new Exception("قابلیت اتصال به فیلدهای قبلی را ندارد " + FieldName + " فیلد");
        //-------------------------
        Condition_Value[Tedad_Item].FieldName = FieldName;
        Condition_Value[Tedad_Item].Operator = Operator;
        Condition_Value[Tedad_Item].Value = Value;
        Condition_Value[Tedad_Item].Concat = Concat;
        Tedad_Item++;
    }
    #endregion
    #region XML
    /// <summary>
    /// .این متد، شرط های مختلف را روی عملیات شما اعمال می کند
    /// </summary>
    /// <param name="FieldName">
    /// .نام فیلدی که می خواهید شرط را روی آن اعمال کنید
    /// </param>
    /// <param name="Operator">
    /// نوع عملیات مقایسه ای
    /// </param>
    /// <param name="Value">
    /// مقدار برای انجام عمل مقایسه
    /// </param>
    #endregion
    #region AddCondition2
    public void AddCondition(String FieldName, Operatotrs Operator, Object Value)
    {
        if (Tedad_Item > Condition_Value.Length)
            throw new Exception("تعداد شرط وارد شده، بیش از تعداد تعیین شده است");
        //-------------------------
        if (Tedad_Item > 0)
            if (Condition_Value[Tedad_Item - 1].Concat == Concat_Type.None)
                throw new Exception("قابلیت اتصال به فیلدهای قبلی را ندارد " + FieldName + " فیلد");
        //-------------------------
        Condition_Value[Tedad_Item].FieldName = FieldName;
        Condition_Value[Tedad_Item].Operator = Operator;
        Condition_Value[Tedad_Item].Value = Value;
        Condition_Value[Tedad_Item].Concat = Concat_Type.None;
        Tedad_Item++;
    }
    #endregion
    #region ResetCondition
    /// <summary>
    /// بازسازی کلاس شرط، برای اعمال شرطهای جدید
    /// </summary>
    /// <param name="Lenght">تعداد شرطهای جدید</param>
    public void ResetCondition(Int16 Lenght)
    {
        Condition_Value = new Conditions[Lenght];
        Tedad_Item = 0;
    }
    #endregion
    #region ReturnTedadItem
    /// <summary>
    /// این متد، تعداد شرطهای اعمال شده به کلاس را برمی گرداند
    /// </summary>
    /// <returns>تعداد شرط اعمال شده</returns>
    public Int16 ReturnTedadItem()
    {
        return Tedad_Item;
    }
    #endregion
    #region ReturnConditions
    /// <summary>
    /// این متد، یکی از شرط های کلاس را برمی گرداند
    /// </summary>
    /// <returns>شماره شرط مورد نظر</returns>
    public Conditions ReturnCondition(Int32 Index)
    {
        if (Index > Tedad_Item)
            throw new Exception("اندیس وارد شده، خارج از محدوده است");
        return Condition_Value[Index];
    }
    #endregion
}
#endregion
//========================================================DataBase Class
#region DataBase Class
public class DataBase_SQL
{
    #region Variables
    public static String Server = "", DataBaseName = "", UserID = "", Password = "";
    public static Boolean IntegratedSecurity = true;
    static SqlConnection Con = new SqlConnection();
    static SqlCommand Cmd = new SqlCommand();
    static SqlDataAdapter DA = new SqlDataAdapter();
    #endregion
    //------------------------------------------------
    #region Initialize
    public static void Initialize()
    {
        if (Server == "" || DataBaseName == "")
            throw new Exception("خصوصیات بانک اطلاعاتی، تعیین نشده است\n" + "را فراخوانی کنید Initialize() لطفا متد");
        if (Con.ConnectionString == "")
        {
            DA.SelectCommand = new SqlCommand();
            Con.ConnectionString = "Data Source=" + Server + ";Initial Catalog=" + DataBaseName + ";Integrated Security=" + IntegratedSecurity.ToString();
            if (UserID != "")
            {
                Con.ConnectionString += ";User ID=" + UserID + ";Password=" + Password;
            }
            Con.Open();
            Cmd.Connection = Con;
            DA.SelectCommand.Connection = Con;
        }
    }
    #endregion
    //------------------------------------------------
    #region Restart DataBase
    /// <summary>
    /// .این متد باعث راه اندازی مجدد عملیات اتصال به پایگاه داده می شود
    /// </summary>
    public static void RestartDB()
    {
        if (Server == "" || DataBaseName == "")
            throw new Exception("خصوصیات بانک اطلاعاتی، تعیین نشده است\n" + "را فراخوانی کنید Initialize() لطفا متد");
        Con.Close();
        Con.ConnectionString = "Data Source=" + Server + ";Initial Catalog=" + DataBaseName + ";Integrated Security=" + IntegratedSecurity.ToString();
        if (UserID != "")
        {
            Con.ConnectionString += ";User ID=" + UserID + ";Password=" + Password;
        }
        Con.Open();
    }
    #endregion
    //------------------------------------------------
    #region XML
    /// <summary>
    /// This method performe all your activities with database.
    /// </summary>
    /// <param name="Operation">
    /// Types Of Operation, Such as : Select, Insert, Update, Delete or StoredProcedure.
    /// </param>
    /// <param name="Cond">
    /// Conditions that you will apply to your SQL statement. Use null in one of this states : 1-You have no condition 2-For insert statement 3-For calling a StoredProcedure. this condition is an instance of 'Condition' class.
    /// </param>
    /// <param name="TableName">
    /// Name of Table or StoredProcedure that you will operate on it.
    /// </param>
    /// <param name="Field_Names">
    /// Necessary fields name (For Select, Insert, Update, Delete) or parameters Name (For StoredProcedure). Such as "Name,Family,Age".
    /// </param>
    /// <param name="SQL_Values">
    /// Values matched with entered fields name or parameters. For example "Reza","Ramezani",20 is matched with "Name,Family,Age". Note that for Select operation, you can use this values for ordering result. You don't need to enter statement 'Order By' at beginning of it, but you can use 'Desc' or 'Asc' statement after it, Such as "Name,Family Desc" that this statement will produce 'Order By Name,Family Desc' automaticly.
    /// </param>
    /// <returns></returns>
    #endregion
    #region Action
    public static DataTable Action(DBOperation Operation, Condition Cond, String TableName, String Field_Names, params object[] SQL_Values)
    {
        Initialize();
        Field_Names = Field_Names.Replace(" ", "").Replace("@", "");
        String[] Parameters_Arr = Field_Names.Split(',');
        if (Parameters_Arr.Length != SQL_Values.Length && Operation != DBOperation.Select && Operation != DBOperation.Delete) throw new Exception("تعداد پارامتر ورودی با تعداد مقادیر ورودی برابر نیست");
        //---------------------------
        Cmd.Parameters.Clear();
        String StrSql = "";
        //======================Insert
        #region Insert Operations
        if (Operation == DBOperation.Insert)
        {
            String Parameters = "";
            for (int i = 0; i < Parameters_Arr.Length; i++)
            {
                Parameters += "@" + Parameters_Arr[i] + ",";
                Cmd.Parameters.AddWithValue("@" + Parameters_Arr[i], SQL_Values[i]);
            }
            Parameters = Parameters.Substring(0, Parameters.Length - 1);
            StrSql = "Insert Into " + TableName + " (" + Field_Names + ") Values (" + Parameters + ")";
            Cmd.CommandText = StrSql;
            Cmd.ExecuteNonQuery();
            return null;
        }
        #endregion
        //======================Update
        #region Update Operations
        else if (Operation == DBOperation.Update)
        {
            String Parameters = "";
            for (int i = 0; i < Parameters_Arr.Length; i++)
            {
                Parameters += Parameters_Arr[i] + "=" + "@" + Parameters_Arr[i] + ",";
                Cmd.Parameters.AddWithValue("@" + Parameters_Arr[i], SQL_Values[i]);
            }
            Cmd.CommandText = "Update " + TableName + " Set " + Parameters.Substring(0, Parameters.Length - 1);
            if (Cond != null)
                if (Cond.ReturnTedadItem() > 0) AddCondition(Cond, Cmd);
            Cmd.ExecuteNonQuery();
            return null;
        }
        #endregion
        //======================Delete
        #region Delete Operations
        else if (Operation == DBOperation.Delete)
        {
            Cmd.CommandText = "Delete From " + TableName;
            if (Cond != null)
                if (Cond.ReturnTedadItem() > 0) AddCondition(Cond, Cmd);
            Cmd.ExecuteNonQuery();
            return null;
        }
        #endregion
        //======================Select|Stored Procedure
        #region Select|Stored Procedure Operations
        else
        {
            DataTable DT1 = new DataTable();
            DA.SelectCommand.Parameters.Clear();
            //----------------------Options For Operating Type
            if (Operation == DBOperation.StoredProcedure)
            {
                DA.SelectCommand.CommandType = CommandType.StoredProcedure;
                DA.SelectCommand.CommandText = TableName;
            }
            else
            {
                SqlCommandBuilder CB = new SqlCommandBuilder(DA);
                DA.SelectCommand.CommandType = CommandType.Text;
                DA.SelectCommand.CommandText = "Select " + Field_Names + " From " + TableName;
            }
            //----------------------Add Parameters For StoredProcedure
            if (Operation == DBOperation.StoredProcedure)
            {
                for (int i = 0; i < Parameters_Arr.Length; i++)
                {
                    DA.SelectCommand.Parameters.AddWithValue("@" + Parameters_Arr[i], SQL_Values[i]);
                }
            }
            //----------------------Apply Condition For Select
            if (Cond != null && Operation == DBOperation.Select)
            {
                if (Cond.ReturnTedadItem() > 0) AddCondition(Cond, DA.SelectCommand);
            }
            //----------------------Apply OrderBy For Select
            if (SQL_Values.Length > 0 && Operation == DBOperation.Select)
            {
                String Order = " Order By ";
                for (int i = 0; i < SQL_Values.Length; i++)
                {
                    Order += SQL_Values[i].ToString();
                    if (i != SQL_Values.Length - 1) Order += ",";
                }
                DA.SelectCommand.CommandText += Order;
            }
            //----------------------Finished Operating
            DA.Fill(DT1);
            return DT1;
        }
        #endregion
    }
    #endregion
    //------------------------------------------------
    #region Update
    /// <summary>
    /// .را در پایگاه داده ثبت می کند Select این متد، تغییرات اعمال شده در خروجی عمل
    /// </summary>
    /// <param name="DT">
    /// .در آن ریخته شده است Select ی که خروجی عملDataTable نام
    /// </param>
    public static void Update(DataTable DT)
    {
        DA.Update(DT);
    }
    /// <summary>
    /// .را در پایگاه داده ثبت می کند Select این متد، تغییرات اعمال شده در خروجی عمل
    /// </summary>
    /// <param name="DGV">
    /// .در آن نمایش داده شده است Select ی که خروجی عملDataGridView نام
    /// </param>
    public static void Update(DataGridView DGV)
    {
        DA.Update((DataTable)DGV.DataSource);
    }
    #endregion
    //------------------------------------------------
    #region AddCondition
    private static void AddCondition(Condition Temp_Cond, SqlCommand Temp_Cmd)
    {
        String Prefix = "@SSG_Group_";
        String Concat, FinalParameter;
        String StrSql = Temp_Cmd.CommandText + " Where ";
        String Operand;
        for (int i = 0; i < Temp_Cond.ReturnTedadItem(); i++)
        {
            switch (Temp_Cond.ReturnCondition(i).Operator)
            {
                case Operatotrs.کوچکتر:
                    Operand = "<";
                    break;
                case Operatotrs.کوچکتر_مساوی:
                    Operand = "<=";
                    break;
                case Operatotrs.مساوی:
                    Operand = "=";
                    break;
                case Operatotrs.بزرگتر:
                    Operand = ">";
                    break;
                case Operatotrs.بزرگتر_مساوی:
                    Operand = ">=";
                    break;
                default:
                    Operand = "=";
                    break;
            }
            //--------------------------
            if (i == Temp_Cond.ReturnTedadItem() || Temp_Cond.ReturnCondition(i).Concat == Concat_Type.None)
                Concat = "";
            else if (Temp_Cond.ReturnCondition(i).Concat == Concat_Type.And)
                Concat = " And ";
            else if (Temp_Cond.ReturnCondition(i).Concat == Concat_Type.Or)
                Concat = " Or ";
            else
                Concat = " ";
            //--------------------------
            FinalParameter = Prefix + Temp_Cond.ReturnCondition(i).FieldName;
            while (Temp_Cmd.Parameters.Contains(FinalParameter)) FinalParameter += "1";
            StrSql += Temp_Cond.ReturnCondition(i).FieldName + Operand + FinalParameter + Concat;
            Temp_Cmd.Parameters.AddWithValue(FinalParameter, Temp_Cond.ReturnCondition(i).Value);
        }
        Temp_Cmd.CommandText = StrSql;
    }
    #endregion
    //------------------------------------------------
    #region Bank Action
    public static void Bank_Action(String StrSQL)
    {
        Initialize();
        Cmd.Parameters.Clear();
        Cmd.CommandText = StrSQL;
        Cmd.ExecuteNonQuery();
    }
    #endregion
    //------------------------------------------------
    #region Bank Select
    public static DataTable Bank_Select(String StrSQL)
    {
        Initialize();
        DataTable DT1 = new DataTable();
        DA.SelectCommand.Parameters.Clear();
        DA.SelectCommand.CommandText = StrSQL;
        DA.Fill(DT1);
        return DT1;
    }
    #endregion
}
#endregion