using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Project.Manager
{
    public struct sModelInfo
    {
        public string Group;
        public string QRCode;
        public int QRx;
        public int QRy;
        public string Asset;
        public string Memo;
        public void Clear()
        {
            Group = string.Empty;
            QRCode = string.Empty;
            QRx = 0;
            QRy = 0;
            Asset = string.Empty;
            Memo = string.Empty;    
        }

    }
    public class ModelManager
    {
        public enum eModelType : int
        {
            Users = 0,
            Model,
        }


        public DataSet1 dataSet;
        private string[] fn;

        public ModelManager()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "Model";
            if (!System.IO.Directory.Exists(path)) System.IO.Directory.CreateDirectory(path);
            this.fn = new string[] { path + "\\Users.csv", path + "\\Model.csv" };
            dataSet = new DataSet1();
        }

        public void LoadData(eModelType model)
        {
            //set filename
            string filename = fn[(int)model];
            int lineCount = 0;
            string buffer = string.Empty;

            FCOMMON.Pub.log.Add("ModelData Load : " + model.ToString() + "fn=" + filename);

            //read file
            var fi = new FileInfo(filename);
            if (fi.Exists == false)
            {
                FCOMMON.Pub.log.AddE(string.Format("▣ No Data",model));
                return;
            }

            lineCount = 0;
            try
            {
                buffer = System.IO.File.ReadAllText(fi.FullName, System.Text.Encoding.Default);
            }
            catch (Exception ex)
            {
                buffer = string.Empty;
                FCOMMON.Pub.log.AddE(string.Format("ItemData Error File={0},Message={1}", filename, ex.Message));
                return;
            }

            //존재하는 컬럼확인을 위해 미리 저장함
            List<String> dbCols = new List<string>();
            foreach (System.Data.DataColumn col in dataSet.Tables[model.ToString()].Columns)
                dbCols.Add(col.ColumnName);

            List<String> Cols = new List<string>();
            foreach (string items in buffer.Split('\r'))
            {
                lineCount += 1;
                var line = items.Replace("\r", "").Replace("\n", "");
                if (line.Trim() == "" || line.StartsWith("ver")) continue; //빈줄과 버젼표기는 제거한다.
                string[] buf = line.Split(',');

                //첫줄에는 컬럼명이 들어있다.
                if (Cols.Count < 1)
                {
                    foreach (string colname in buf)
                    {
                        if (colname.isEmpty()) continue; //비어있는값은 처리하지 않는다.
                        Cols.Add(colname);
                    }
                    continue;
                }

                //데이터를 각 컬럼에 넣는다.
                System.Data.DataRow dr = dataSet.Tables[model.ToString()].NewRow();

                //비젼속성은 컬럼명이 v_로 시작한다.
                for (int i = 0; i < Cols.Count; i++) //0번은 Mccode이므로 제외한다.
                {
                    try
                    {
                        if (dbCols.IndexOf(Cols[i]) == -1) continue; //존재하지 않는 컬럼은 제외한다.
                        if (Cols[i].ToUpper() == "IDX") continue;
                        dr[Cols[i]] = buf[i+1];
                    }
                    catch (Exception ex)
                    {
                        FCOMMON.Pub.log.AddE("Item Load Error:" + ex.Message);
                    }
                }

                
                try
                {
                    if (dr.RowState == System.Data.DataRowState.Detached)
                    {
                        dataSet.Tables[model.ToString()].Rows.Add(dr);
                    }
                    else if (dr.RowState != System.Data.DataRowState.Deleted) dr.EndEdit();
                }
                catch (Exception ex)
                {
                    FCOMMON.Pub.log.AddE("Load Item file" + ex.Message);
                }
            }

            dataSet.AcceptChanges();
        }

        /// <summary>
        /// project , model read from file
        /// </summary>
        public void Load()
        {
            //데이터셋 초기화
            if (dataSet == null) dataSet = new DataSet1();
            else dataSet.Clear();

            //파일로부터 데이터를 읽어들인다.
            this.LoadData(eModelType.Users);
            this.LoadData(eModelType.Model);
            this.dataSet.AcceptChanges();

            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("model data list");
            for(int i = 0; i< dataSet.Tables.Count;i++)
            {
                var dt = dataSet.Tables[i];
                if (dt.TableName.ToLower() == "resultdata") continue;
                sb.AppendLine(dt.TableName + " : " + dt.Rows.Count.ToString() + "건");
            }

            FCOMMON.Pub.log.AddI(sb.ToString());
        }

        public void Save()
        {
            this.dataSet.AcceptChanges();
            System.IO.DirectoryInfo di = new DirectoryInfo (Util.CurrentPath + "\\Model");
            if (!di.Exists) di.Create();
            SaveData(eModelType.Users);
            SaveData(eModelType.Model);
        }

        public void SaveData(eModelType model)
        {
            var data = new StringBuilder();
            data.AppendLine("ver,:" + model.ToString()); //version

            List<string> baseCols = new List<string>();
            if (model == eModelType.Users) baseCols.AddRange(new string[] { "No", "Name", "Memo" });
            else if (model == eModelType.Model) baseCols.AddRange(new string[] { "Group", "Asset" });
            
            List<String> cols = new List<string>();
            foreach (System.Data.DataColumn col in this.dataSet.Tables[model.ToString()].Columns)
            {
                string colname = col.ColumnName.ToLower();
                if (colname == "idx" || colname.StartsWith("_")) continue; //기본열은 제외한다.
                if (baseCols.IndexOf(col.ColumnName) >= 0) continue;
                cols.Add(col.ColumnName);
            }

            //열을 정렬해서 추가한다.
            var bb = cols.OrderBy(t => t);
            baseCols.AddRange(bb);  //정렬된 열을 추가해준다.

            foreach (string colname in baseCols)
                data.Append("," + colname);
            data.AppendLine();

            //output data(글로벌 셋팅하고 MC코드값만 취한다)v
            var dt = dataSet.Tables[model.ToString()];
            var drows = dt.Select("", "idx");
            foreach (var dr in drows)
            {
                foreach (string colname in baseCols) //지정된 열제목의 데이터를 가져온다.
                {
                    data.Append(",");
                    if (dr[colname] != DBNull.Value) data.Append(dr[colname].ToString());
                    else if (dt.Columns[colname].DataType == typeof(double) ||
                        dt.Columns[colname].DataType == typeof(Int32) ||
                        dt.Columns[colname].DataType == typeof(UInt32) ||
                        dt.Columns[colname].DataType == typeof(Single) ||
                        dt.Columns[colname].DataType == typeof(byte) ||
                        dt.Columns[colname].DataType == typeof(Boolean) ||
                        dt.Columns[colname].DataType == typeof(Int16) ||
                        dt.Columns[colname].DataType == typeof(UInt16))
                    {
                        if (dt.Columns[colname].DataType == typeof(Boolean)) data.Append("False");
                        else data.Append("0");
                    }
                    else data.Append("");
                }
                data.AppendLine();
            }
            try
            {
                System.IO.File.WriteAllText(fn[(int)model], data.ToString(), System.Text.Encoding.Default);
                FCOMMON.Pub.log.AddAT("Save "+ model.ToString()+" Parameter - OK");
            }
            catch (Exception ex)
            {
                Util.MsgE("Save Error\r\n" + ex.Message);
                FCOMMON.Pub.log.AddE("Save Error :: " + ex.Message);
            }
        }
      
       
       
        public DataSet1.UsersRow GetUser(string no)
        {
            var datas = this.dataSet.Users.Where(t => t.No == no);
            if (datas.Count() < 1) return null;
            return datas.First();
        }
        public DataSet1.UsersRow[] GetUsers()
        {
            var datas = dataSet.Users.Select("", "No");
            if (datas.Length < 1) return null;
            return datas as DataSet1.UsersRow[];
        }

        public DataSet1.ModelRow GetModel(string Asset)
        {
            if (Asset.isEmpty()) return null;
            if (dataSet.Model == null || dataSet.Model.Rows.Count < 1) return null;
            var datas = dataSet.Model.Where(t => t.Asset == Asset).ToArray();
            if (datas.Length != 1) return null;
            return datas[0];
        }
        public sModelInfo GetModelInfo(string qrData)
        {
            sModelInfo retval = new sModelInfo();
            retval.Clear();
            var model = GetModel(qrData);
            if(model != null)
            {
                retval.Asset = model.Asset;
                retval.Memo = model.Memo;
            }
            return retval;
        }
        
    }

}
