using AR;
using Org.BouncyCastle.Bcpg.OpenPgp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Net.WebRequestMethods;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace UniMarc
{
    public partial class Marc_Plan : Form
    {
        Main main;
        Helper_DB db = new Helper_DB();
        string date = "";

        public Marc_Plan(Main _main)
        {
            InitializeComponent();
            main = _main;
            this.btDelete.Visible = System.Diagnostics.Debugger.IsAttached;
            
            // Configure Binding
            dataGridView1.AutoGenerateColumns = false;
            // Map columns
            dataGridView1.Columns["idx"].DataPropertyName = "Idx";
            dataGridView1.Columns["num"].DataPropertyName = "Num";
            dataGridView1.Columns["reg_num"].DataPropertyName = "RegNum";
            dataGridView1.Columns["class_code"].DataPropertyName = "ClassCode";
            dataGridView1.Columns["author_code"].DataPropertyName = "AuthorCode";
            dataGridView1.Columns["volume"].DataPropertyName = "Volume";
            dataGridView1.Columns["copy"].DataPropertyName = "Copy";
            dataGridView1.Columns["prefix"].DataPropertyName = "Prefix";
            dataGridView1.Columns["gu"].DataPropertyName = "Gu";
            dataGridView1.Columns["ISBN"].DataPropertyName = "Isbn";
            dataGridView1.Columns["book_name"].DataPropertyName = "BookName";
            dataGridView1.Columns["s_book_name1"].DataPropertyName = "SBookName1";
            dataGridView1.Columns["s_book_num1"].DataPropertyName = "SBookNum1";
            dataGridView1.Columns["s_book_name2"].DataPropertyName = "SBookName2";
            dataGridView1.Columns["s_book_num2"].DataPropertyName = "SBookNum2";
            dataGridView1.Columns["author"].DataPropertyName = "Author";
            dataGridView1.Columns["book_comp"].DataPropertyName = "BookComp";
            dataGridView1.Columns["price"].DataPropertyName = "Price";
            dataGridView1.Columns["midx"].DataPropertyName = "Midx";
            dataGridView1.Columns["marc"].DataPropertyName = "Marc";
            dataGridView1.Columns["search_tag2"].DataPropertyName = "SearchTag2";
            dataGridView1.Columns["colCheck"].DataPropertyName = "ColCheck";
            // CheckBox column value mapping is usually handled automatically for True/False value types if configured, 
            // but since we using string "T"/"F", we might need cell formatting or just stick to using a helper property if grid supports it.
            // The existing code uses "T"/"F". The DataGridViewCheckBoxColumn TrueValue/FalseValue defaults are usually bool.
            // I should set TrueValue/FalseValue for the column to "T"/"F" in Designer or code.
            // Assuming default is bool, let's try to stick to logic.
            ((DataGridViewCheckBoxColumn)dataGridView1.Columns["colCheck"]).TrueValue = "T";
            ((DataGridViewCheckBoxColumn)dataGridView1.Columns["colCheck"]).FalseValue = "F";
            
            this.bs1.DataSource = typeof(MarcPlanItem);
            this.dataGridView1.DataSource = this.bs1;
        }

        private void Marc_Plan_Load(object sender, EventArgs e)
        {
            db.DBcon();

            AuthorSymbol.Symbol sb = new AuthorSymbol.Symbol();
            cb_FirstAuthor.Items.AddRange(sb.authorBook);
            cb_authorTypeK.Items.AddRange(sb.authorType);
            cb_authorTypeE.Items.AddRange(sb.authorType);
            cb_FirstBook.Items.AddRange(sb.authorFirst);

            string[] divType = { "KDC", "DDC" };
            cb_divType.Items.AddRange(divType);

            string[] divNum = { "4", "5", "6" };
            cb_divNum.Items.AddRange(divNum);

            string[] Encoding = { "ANSI", "UTF-8", "UniCode" };
            cb_EncodingType.Items.AddRange(Encoding);
            cb_EncodingType.SelectedIndex = 0;

            // string[] Font = { "굴림", "굴림체", "돋움", "바탕체", "맑은 고딕", "HY강B", "HY강M" };
            // cb_TextFont.Items.AddRange(Font);
            String_Text st = new String_Text();
            cb_TextFont.Items.AddRange(st.callMyFont());
        }

        private void btn_Select_List_Click(object sender, EventArgs e)
        {
            tb_ISBN.Text = "";

            Marc_Plan_Sub_SelectList sub = new Marc_Plan_Sub_SelectList();
            sub.TopMost = true;
            if (sub.ShowDialog() == DialogResult.OK)
            {
                //데이터가 있다면?
                if (sub.ResultItems != null && sub.ResultItems.Any())
                {
                    bs1.DataSource = sub.ResultItems;
                }
                else if (sub.ResultIdx >= 0)
                {
                    mk_Grid(sub.ResultListName, sub.ResultDate);
                    mk_Panel(sub.ResultIdx, sub.ResultListName, sub.ResultDate);
                }
            }
            dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
        }

        #region SelectList_Sub

        public void mk_Grid(string ListName, string date)
        {
            btn_Select_List.Text = ListName;
            this.date = date;
            dataGridView1.Rows.Clear();

            string Table = "Specs_Marc";

            String_Text st = new String_Text();

            // L V C F A B
            string[] GetTag = { "049v", "049c", "049f" };
            string[] GetTag2 = { "090a", "090b" };
            // idx 연번 등록번호 분류기호 저자기호
            // V(049v,볼륨) C(049c,복본) F(049f,별치) 구분(이용자) ISBN
            // 도서명 총서명 총서번호 총서명1 총서명1
            // 저자 출판사 정가 midx 마크

            // idx
            // 연번 등록번호 분류기호 저자기호 ISBN
            // 도서명 총서명1 총서번호1 총서명2 총서번호2
            // 저자 출판사 정가 midx 마크데이터
            string Area = "`idx`, "
                        + "`num`, `r_num`, `class_symbol`, `author_symbol`, `ISBN`, "
                        + "`book_name`, `s_book_name1`, `s_book_num1`, `s_book_name2`, `s_book_num2`, "
                        + "`author`, `book_comp`, `price`, `midx`, `marc`, `etc1`, `etc2`, `grade`";

            string[] Search_col = { "work_list", "date" };
            string[] Search_data = { ListName, date };
            string cmd = db.More_DB_Search(Table, Search_col, Search_data, Area);
            var res = Helper_DB.ExecuteDataTable(cmd); // Assumed called above
            var list = new List<MarcPlanItem>();
            int tCnt = 1;
           
            foreach (DataRow dr in res.Rows)
            {
                MarcPlanItem item = new MarcPlanItem();
                item.Idx = dr["idx"] != DBNull.Value ? Convert.ToInt32(dr["idx"]) : 0;
                item.Num = dr["num"].ToString();
                if (string.IsNullOrEmpty(item.Num))
                {
                    item.Num = tCnt.ToString();
                }
                tCnt++;

                item.RegNum = dr["r_num"].ToString();
                item.ClassCode = dr["class_symbol"].ToString();
                item.AuthorCode = dr["author_symbol"].ToString();
                item.Isbn = dr["ISBN"].ToString();
                item.BookName = dr["book_name"].ToString();
                item.SBookName1 = dr["s_book_name1"].ToString();
                item.SBookNum1 = dr["s_book_num1"].ToString();
                item.SBookName2 = dr["s_book_name2"].ToString();
                item.SBookNum2 = dr["s_book_num2"].ToString();
                item.Author = dr["author"].ToString();
                item.BookComp = dr["book_comp"].ToString();
                item.Price = dr["price"] != DBNull.Value ? Convert.ToInt32(dr["price"]) : 0;
                item.Midx = dr["midx"] != DBNull.Value ? Convert.ToInt32(dr["midx"]) : 0;
                item.etc1 = dr["etc1"]?.ToString() ?? string.Empty;
                item.etc2 = dr["etc2"]?.ToString() ?? string.Empty;
                item.grade = dr["grade"] != DBNull.Value ? Convert.ToInt32(dr["grade"]) : -1;    

                string rawMarc = dr["marc"].ToString();

                // Logic for MARC tag processing
                string[] vcf = st.Take_Tag(rawMarc, GetTag);
                item.Volume = vcf[0];
                item.Copy = vcf[1];
                item.Prefix = vcf[2];

                string[] ab = st.Take_Tag(rawMarc, GetTag2);
                if (ab[0] != "")
                    rawMarc = rawMarc.Replace(ab[0], item.ClassCode);
                if (ab[1] != "")
                    rawMarc = rawMarc.Replace(ab[1], item.AuthorCode);

                string[] vcf_marc = new string[] { "", "", "" };
                vcf_marc[0] = string.Format("▼a{0}", item.ClassCode);
                vcf_marc[1] = string.Format("▼b{0}", item.AuthorCode);
                if (!string.IsNullOrEmpty(item.Volume))
                    vcf_marc[2] = string.Format("▼c{0}", item.Volume);
                
                string AddTag = string.Format("090\t  \t{0}{1}{2}▲", vcf_marc[0], vcf_marc[1], vcf_marc[2]);
                string TypeView = ConvertMarcType(rawMarc);
                item.Marc = st.made_Ori_marc(AddTagInMarc(AddTag, TypeView));

                item.ColCheck = "F"; 

                list.Add(item);
            }
            bs1.DataSource = list;
     
        }

        
        public void mk_Panel(int idx, string ListName, string date)
        {
            string Table = "Specs_List";
            string Area = "`first_Author`, `symbol_Author`,`symbol_AuthorE`,  `book_Author`, `divType`, `divNum`";
            string[] Search_col = { "idx", "work_list", "date" };
            string[] Search_data = { idx.ToString(), ListName, date };

            string cmd = db.More_DB_Search(Table, Search_col, Search_data, Area);
            string res = db.DB_Send_CMD_Search(cmd);

            string[] ary = res.Split('|');

            cb_FirstAuthor.SelectedItem = ary[0];
            cb_authorTypeK.SelectedItem = ary[1];
            cb_authorTypeE.SelectedItem = ary[2];
            cb_FirstBook.SelectedItem = ary[3];
            cb_divType.SelectedItem = ary[4];
            cb_divNum.SelectedItem = ary[5];
        }
        #endregion



        private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Skill_Grid sg = new Skill_Grid();
            sg.Print_Grid_Num(sender, e);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            foreach (DataGridViewRow r in dataGridView1.Rows)
            {
                if (((CheckBox)sender).Checked)
                    r.Cells["colCheck"].Value = "T";
                else
                    r.Cells["colCheck"].Value = "F";
            }
        }

        private (string marc, MacEditorParameter p) GetBookData(MarcPlanItem item)
        {
            string bookName = item.BookName;
            string author = item.Author;
            string publisher = item.BookComp;
            var price = item.Price;
            string isbn = item.Isbn;
            var idx = item.Idx;
            var midx = item.Midx;
            string marc = item.Marc;

            string cmd = string.Format("SELECT `user`, `editDate`, `etc1`, `etc2` FROM `Specs_Marc` WHERE `idx` = \"{0}\"", midx);
            string res = db.DB_Send_CMD_Search(cmd);
            string[] aryResultData = res.Split('|');
            string remark1 = "";
            string remark2 = "";

            if (aryResultData.Length > 1) {
                // lbl_SaveData.Text = string.Format("[{0}] [{1}]", aryResultData[0], aryResultData[1]);
                remark1 = aryResultData[2];
                remark2 = aryResultData[3];
            }

            var p = new MacEditorParameter
            {
                ISBN13 = isbn,
                ListIdx = idx,
                MarcIdx = midx,
                SaveDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), // temporary
                User = main.botUserLabel.Text,
                BookName = bookName,
                Author = author,
                Publisher = publisher,
                Price = price,
            };
            return (marc, p);
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            int row = e.RowIndex;
            int col = e.ColumnIndex;

            if (row < 0) return;

            if (dataGridView1.Rows[row].Cells[col].ReadOnly)
            {
                if (chkEditorTest.Checked == true)
                {
                    string[] Marc = {
                        dataGridView1.Rows[row].Cells["marc"].Value.ToString(),
                        dataGridView1.Rows[row].Cells["midx"].Value.ToString(),
                        dataGridView1.Rows[row].Cells["num"].Value.ToString(),
                        dataGridView1.Rows[row].Cells["idx"].Value.ToString(),
                        dataGridView1.Rows[row].Cells["ISBN"].Value.ToString()
                    };
                    string[] symbol_Type = {
                        cb_FirstAuthor.Text, cb_authorTypeK.Text, cb_authorTypeE.Text, cb_FirstBook.Text,
                        cb_divType.Text, cb_divNum.Text
                    };
                    Marc_Plan_Sub_MarcEdit me = new Marc_Plan_Sub_MarcEdit(this);
                    me.row = row;
                    me.UserName = main.botUserLabel.Text;
                    me.Init(Marc);
                    me.SetSymbolType(symbol_Type);
                    me.Show();
                }
                else
                {
                    // Sync BindingSource position
                    bs1.Position = row;
                    
                    var dr = (MarcPlanItem)bs1.Current;
                    string isbn = dr.Isbn;
                    string marcData = dr.Marc;

                    var f = new fMarc_Editor(isbn, marcData, SaveTarget.SpecsMarc,dr.etc1, dr.etc2,dr.grade);
                    var data = GetBookData(dr);
                    f.LoadBook(data.marc, data.p);
                    f.RequestNext += (s, args) =>
                    {
                        if (bs1.Position < bs1.Count - 1)
                        {
                            bs1.MoveNext();
                            var nextItem = (MarcPlanItem)bs1.Current;
                            var nextData = GetBookData(nextItem);
                            f.LoadBook(nextData.marc, nextData.p);
                            
                            // Optional: Ensure visible
                            //if (dataGridView1.CurrentRow != null)
                                //dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.CurrentRow.Index;
                        }
                    };

                    f.RequestPrev += (s, args) =>
                    {
                        if (bs1.Position > 0)
                        {
                            bs1.MovePrevious();
                            var prevItem = (MarcPlanItem)bs1.Current;
                            var prevData = GetBookData(prevItem);
                            f.LoadBook(prevData.marc, prevData.p);
                            
                             // Optional: Ensure visible
                            //if (dataGridView1.CurrentRow != null)
                              //  dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.CurrentRow.Index;
                        }
                    };

                    f.BookUpdated += (s, args) =>
                    {
                        var item = (MarcPlanItem)bs1.Current;
                        item.BookName = args.BookName;
                        item.Marc = args.Marc;
                        bs1.ResetCurrentItem(); // Refresh grid
                    };

                    f.RequestFillBlankData += (s, args) =>
                    {
                        var dataList = new List<FillBlankItem>();
                        var currentBoundItem = (MarcPlanItem)bs1.Current;
                        
                        for (int a = 0; a < bs1.Count; a++)
                        {
                            // Criteria for "Fill Blank" candidates. 
                            // Check if MARC is empty or short
                            var mItem = (MarcPlanItem)bs1.List[a];
                            string mData = mItem.Marc ?? "";
                             if (mData.Length < 10) 
                            {
                                var item = new FillBlankItem
                                {
                                    Idx = a, 
                                    Isbn = mItem.Isbn ?? "",
                                    BookName = mItem.BookName ?? "",
                                    Author = mItem.Author ?? "",
                                    Publisher = mItem.BookComp ?? "",
                                    Price = mItem.Price
                                };
                                dataList.Add(item);
                            }
                        }
                        if(dataList.Any()==false)
                        {
                            UTIL.MsgE("비마크 데이터가 존재하지 않아 기능을 사용할 수 없습니다");
                        }
                        else f.OpenFillBlank(dataList, currentBoundItem.Isbn);
                    };

                    f.BulkBooksUpdated += (s, args) =>
                    {
                        foreach (var fbItem in args.Updates)
                        {
                            if (string.IsNullOrEmpty(fbItem.BookMarc)) continue;

                            int rowIdx = fbItem.Idx;
                            if (rowIdx >= 0 && rowIdx < bs1.Count)
                            {
                                var mItem = (MarcPlanItem)bs1.List[rowIdx];
                                mItem.Marc = fbItem.BookMarc;
                            }
                        }
                        bs1.ResetBindings(false); // Refresh all to reflect changes
                    };
                    
                    f.Show();
                }
            }
        }

        private void cb_divType_SelectedIndexChanged(object sender, EventArgs e)
        {
            cb_divNum.Items.Clear();

            string value = cb_divType.SelectedItem.ToString();
            if (value == "KDC")
            {
                string[] data = { "4", "5", "6" };
                cb_divNum.Items.AddRange(data);
            }
            else
            {
                string[] data = { "21", "22", "23" };
                cb_divNum.Items.AddRange(data);
            }
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            int row = dataGridView1.CurrentRow.Index;
            string isbn = dataGridView1.Rows[row].Cells["isbn"].Value.ToString();

            tb_ISBN.Text = isbn;
        }

        private void tb_SearchTag_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                Search_Tag();
            }
        }
        #region SearchTag_KeyDown_Sub

        readonly List<string> BackUpTag = new List<string>();
        private void Search_Tag()
        {
            BackUpTag.Clear();
            string[] SearchTag = { tb_SearchTag.Text };
            String_Text st = new String_Text();

            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                string marc = dataGridView1.Rows[a].Cells["marc"].Value.ToString();
                string[] tag = st.Take_Tag(marc, SearchTag, true);
                dataGridView1.Rows[a].Cells["search_tag2"].Value = tag[0];
                BackUpTag.Add(tag[0]);
            }
        }
        #endregion

        private void btn_ChangeTag_Click(object sender, EventArgs e)
        {
            string msg = string.Format("『{0}』 태그를 변경하시겠습니까?", tb_SearchTag.Text);

            // 아니오 선택시 아래코드 실행되지않음.
            if (UTIL.MsgQ(msg) == DialogResult.No) return;

            if (tb_SearchTag.Text.Length <= 3)
            {
                UTIL.MsgE("변경할 태그 검색을 양식에 맞춰주세요. ex) 245a");
                return;
            }

            string TagNum = tb_SearchTag.Text.Substring(0, 3);
            int ConvertTag = Convert.ToInt32(TagNum);
            string TagName = tb_SearchTag.Text.Substring(tb_SearchTag.Text.Length - 1);

            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                string Content = string.Empty;
                if (dataGridView1.Rows[a].Cells["search_tag2"].Value != null)
                    Content = dataGridView1.Rows[a].Cells["search_tag2"].Value.ToString();
                else if (dataGridView1.Rows[a].Cells["search_tag2"].Value == null)
                    Content = "delete";
                if (Content == "") continue;
                string marc = dataGridView1.Rows[a].Cells["marc"].Value.ToString();
                string viewMarc = split_Marc(marc);

                string MakeMarcLine = string.Format("{0}\t  \t▼{1}{2}▲", TagNum, TagName, Content);
                List<string> AryMarc = new List<string>(viewMarc.Split('\n'));

                int index = 0;
                foreach (string LineMarc in AryMarc)
                {
                    int TagInt = Convert.ToInt32(LineMarc.Substring(0, 3));

                    // 해당 마크가 존재하는 태그일 경우
                    if (ConvertTag == TagInt)
                    {
                        string oldTag = string.Format("▼{0}{1}", TagName, BackUpTag[a]);
                        string newTag = string.Format("▼{0}{1}", TagName, Content);
                        if (ConvertTag == 8)
                        {
                            oldTag = BackUpTag[a];
                            newTag = Content;
                        }
                        // 해당 식별기호가 존재할 경우
                        if (LineMarc.Contains(oldTag))
                        {
                            if (Content == "delete")
                            {
                                AryMarc[index] = AryMarc[index].Replace(oldTag, "");
                                int tLength = AryMarc[index].Length;
                                if (tLength <= 8) AryMarc[index] = "";
                            }
                            else
                                AryMarc[index] = LineMarc.Replace(oldTag, newTag);
                            break;
                        }

                        // 해당 식별기호가 존재하지 않을 경우
                        else
                        {
                            // 뷰어형태로 전환하여 삽입하는 형식이라 디렉토리부분은 크게 신경쓰지않아도 됨.
                            // 그렇지만 식별기호가 존재하지않으면 해당 태그의 식별기호 순서를 다 설정하고 그에 맞게 적용되는 시스템이 되어야 함.
                            // 작업이 무척 까다로워질것으로 예상됨.
                        }
                    }

                    // 해당 마크가 존재하지 않는 태그일 경우
                    else if (ConvertTag < TagInt)
                    {
                        AryMarc.Insert(index, MakeMarcLine);
                        break;
                    }
                    index++;
                }
                AryMarc.RemoveAll(x => x == "");
                String_Text st = new String_Text();
                dataGridView1.Rows[a].Cells["marc"].Value = st.made_Ori_marc(string.Join("\n", AryMarc));
            }

            #region 보류
            /*
            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                string marc = dataGridView1.Rows[a].Cells["marc"].Value.ToString();
                string changeTag = dataGridView1.Rows[a].Cells["search_tag2"].Value.ToString();

                if (changeTag == "")
                    continue;

                if (dataGridView1.Rows[a].Cells["colCheck"].Value.ToString() == "T")
                    dataGridView1.Rows[a].Cells["marc"].Value = marc.Replace(BackUpTag[a], changeTag);
            }
            */
            #endregion

            UTIL.MsgI("변경되었습니다!");
        }

        /// <summary>
        /// 마크데이터가 있는지 확인하고 메모장으로 출력
        /// </summary>
        /// <param name="row">마크 데이터</param>
        /// <returns></returns>
        string split_Marc(string Marc_data)
        {
            if (Marc_data.Length < 3) return "";

            string result = string.Empty;

            List<string> TagNum = new List<string>();   // 태그번호
            List<string> field = new List<string>();    // 가변길이필드 저장

            // 특수기호 육안으로 확인하기 쉽게 변환
            Marc_data = Marc_data.Replace("", "▼");
            Marc_data = Marc_data.Replace("", "▲");
            Marc_data = Marc_data.Replace("￦", "\\");
            // string leader = Marc_data.Substring(0, 24);

            int startidx = 0;
            string[] data = Marc_data.Substring(24).Split('▲'); // 리더부를 제외한 디렉터리, 가변길이필드 저장

            // List에 필요한 데이터 집어넣는 작업.
            for (int a = 1; a < data.Length - 1; a++)
            {
                TagNum.Add(data[0].Substring(startidx, 3));
                startidx += 12;
                field.Add(data[a] + "▲");
            }

            // List에 들어간 데이터를 메모장에 출력시키는 작업.
            for (int a = 0; a < TagNum.Count; a++)
            {
                string res = TagNum[a];
                //if (TagNum[a] == "008")
                //{
                //    //text008.Text = field[a].Replace("▲", "");
                //    continue;
                //}
                //else { }
                if (field[a].IndexOf("▼") == -1)
                {
                    res += "\t  \t" + field[a];
                }
                else
                {
                    string temp = field[a].Insert(2, "\t");
                    res += "\t" + temp;
                }
                result += res + "\n";
            }
            return result;
        }

        private void btn_Save_Click(object sender, EventArgs e)
        {
            string table = "Specs_Marc";
            string[] Edit_Col = { "marc", "r_num", "class_symbol", "author_symbol", "prefix", "price", "user", "editDate" };
            string[] Where_Col = { "idx" };

            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                string[] Edit_Data = {
                    dataGridView1.Rows[a].Cells["marc"].Value.ToString(),
                    dataGridView1.Rows[a].Cells["reg_num"].Value.ToString(),
                    dataGridView1.Rows[a].Cells["class_code"].Value.ToString(),
                    dataGridView1.Rows[a].Cells["author_code"].Value.ToString(),
                    dataGridView1.Rows[a].Cells["prefix"].Value.ToString(),
                    dataGridView1.Rows[a].Cells["price"].Value.ToString(),
                    main.botUserLabel.Text,
                    DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") };
                string[] Where_Data = {
                    dataGridView1.Rows[a].Cells["idx"].Value.ToString() };

                string Ucmd = db.More_Update(table, Edit_Col, Edit_Data, Where_Col, Where_Data);
                Helper_DB.ExcuteNonQuery(Ucmd);
            }

            UTIL.MsgI("저장되었습니다.");
            mk_Grid(btn_Select_List.Text, this.date);
        }

        private void btn_Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Excel_Click(object sender, EventArgs e)
        {
            if (dataGridView1.RowCount <= 0) return;

            string[] Tag = { "245n", "245p", "260c" };

            String_Text st = new String_Text();
            Excel_text et = new Excel_text();
            string[] Title = {
                "연번", "등록번호", "분류기호", "저자기호", "볼륨",
                "복본", "별치", "도서명", "원서명", "권차명",
                "권차서명", "총서명", "총서번호", "총서명", "총서번호",
                "저자", "출판사", "출판년", "정가", "ISBN"
            };
            string[,] Content = new string[dataGridView1.RowCount, 20];

            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                string Marc = dataGridView1.Rows[a].Cells["marc"].Value.ToString();
                string[] SearchTag = st.Take_Tag(Marc, Tag);
                string oriBookName = st.TakeTag_FilterJisi(Marc, "246a", "19");

                Content[a, 00] = dataGridView1.Rows[a].Cells["num"].Value.ToString();
                Content[a, 01] = dataGridView1.Rows[a].Cells["reg_num"].Value.ToString();
                Content[a, 02] = dataGridView1.Rows[a].Cells["class_code"].Value.ToString();
                Content[a, 03] = dataGridView1.Rows[a].Cells["author_code"].Value.ToString();
                Content[a, 04] = dataGridView1.Rows[a].Cells["volume"].Value.ToString();

                Content[a, 05] = dataGridView1.Rows[a].Cells["copy"].Value.ToString();
                Content[a, 06] = dataGridView1.Rows[a].Cells["prefix"].Value.ToString();
                Content[a, 07] = dataGridView1.Rows[a].Cells["book_name"].Value.ToString();
                Content[a, 08] = oriBookName;
                Content[a, 09] = SearchTag[0];

                Content[a, 10] = SearchTag[1];
                Content[a, 11] = dataGridView1.Rows[a].Cells["s_book_name1"].Value.ToString();
                Content[a, 12] = dataGridView1.Rows[a].Cells["s_book_num1"].Value.ToString();
                Content[a, 13] = dataGridView1.Rows[a].Cells["s_book_name2"].Value.ToString();
                Content[a, 14] = dataGridView1.Rows[a].Cells["s_book_num2"].Value.ToString();

                Content[a, 15] = dataGridView1.Rows[a].Cells["author"].Value.ToString();
                Content[a, 16] = dataGridView1.Rows[a].Cells["book_comp"].Value.ToString();
                Content[a, 17] = SearchTag[2];
                Content[a, 18] = dataGridView1.Rows[a].Cells["price"].Value.ToString();
                Content[a, 19] = dataGridView1.Rows[a].Cells["ISBN"].Value.ToString();
            }

            et.Mk_Excel(Title, Content);
        }

        private void btn_Output_Click(object sender, EventArgs e)
        {
            String_Text st = new String_Text();
            string Marc_data = string.Empty;

            string FileEncodingType = "";

            switch (cb_EncodingType.SelectedIndex)
            {
                case 0: FileEncodingType = "ANSI"; break;
                case 1: FileEncodingType = "UTF-8"; break;
                case 2: FileEncodingType = "UniCode"; break;
                default: break;
            }

            string totalerrmsg = "";
            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                if (dataGridView1.Rows[a].Cells["marc"].Value.ToString() == "" &&
                    dataGridView1.Rows[a].Cells["marc"].Value == null)
                    continue;

                if (dataGridView1.Rows[a].Cells["colCheck"].Value.ToString() != "T")
                    continue;

                if (a == 825) Console.WriteLine("test");
                string marc = dataGridView1.Rows[a].Cells["Marc"].Value.ToString().Replace("￦", "\\");
                marc = st.ConvertMarcType(marc, out string errmesage);
                marc = st.made_Ori_marc(marc, FileEncodingType);
                Marc_data += marc;
                if (errmesage.isEmpty() == false) totalerrmsg += (totalerrmsg.isEmpty() ? "\n" : "") + errmesage;
            }

            if (totalerrmsg.isEmpty() == false)
                UTIL.MsgI("경고 발생\n" + totalerrmsg);

            string FileName;
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "저장 경로를 지정하세요.";
            saveFileDialog.OverwritePrompt = true;
            saveFileDialog.Filter = "마크 파일 (*.mrc)|*.mrc|모든 파일 (*.*)|*.*";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (FileEncodingType == "ANSI")
                {
                    FileName = saveFileDialog.FileName;
                    System.IO.File.WriteAllText(FileName, Marc_data, Encoding.Default);
                }
                else if (FileEncodingType == "UTF-8")
                {
                    FileName = saveFileDialog.FileName;
                    System.IO.File.WriteAllText(FileName, Marc_data, Encoding.UTF8);
                }
                else if (FileEncodingType == "UniCode")
                {
                    FileName = saveFileDialog.FileName;
                    System.IO.File.WriteAllText(FileName, Marc_data, Encoding.Unicode);
                }
                UTIL.MsgI("반출되었습니다!");
            }

        }

        private void btn_ApplyMacro_Click(object sender, EventArgs e)
        {
            Set_Macro sm = new Set_Macro(this, dataGridView1);
            sm.ViewMarcArray = Make_MarcArray(out string errmessage);
            sm.Show();
            if (errmessage.isEmpty() == false)
                UTIL.MsgI("경고 발생\n" + errmessage);
        }
        private void btnTag040_Click(object sender, EventArgs e)
        {
            string[] tData = Make_MarcArray(out string errmessage);
            if (errmessage.isEmpty() == false)
                UTIL.MsgI("경고 발생\n" + errmessage);

            string tNewTagData = tbTag040.Text;
            List<string> tSplitMarc;
            for (int i = 0; i < tData.Length; i++)
            {
                tSplitMarc = new List<string>(tData[i].Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries));

                int tIDX = tSplitMarc.FindIndex(x => x.Substring(0, 3) == "040");
                int tInsertIDX = tIDX;
                if (dataGridView1.Rows[i].Cells["marc"].Value.ToString() == "" &&
                    dataGridView1.Rows[i].Cells["marc"].Value == null)
                    continue;

                //기존의 040 테그 삭제 부분
                if (tIDX != -1) tSplitMarc.RemoveAt(tIDX);
                else
                {
                    tInsertIDX = tSplitMarc.FindLastIndex(x =>
                        {
                            int tReturn = 1;
                            int.TryParse(x.Substring(0, 3), out tReturn);
                            return tReturn < 40;
                        });
                }
                // 신규 040 테그 삽입
                string tInsertTag = string.Format("040\t  \t▼a{0}▲", tNewTagData);
                tSplitMarc.Insert(tInsertIDX + 1, tInsertTag);
                //ViewMarc = st.AddTagInMarc("500\t  \t▼aURL 링크 클릭한 후 전자도서 홈페이지에서 로그인하여 이용하시기 바랍니다.▲", ViewMarc);
                string tChange = string.Join("\n", tSplitMarc);
                String_Text st = new String_Text();
                dataGridView1.Rows[i].Cells["marc"].Value = st.made_Ori_marc(tChange);
            }
            UTIL.MsgI("태그 일괄 적용 완료!");
        }
        private List<int> GetSelectGridIDX()
        {
            List<int> tSelectIDX = new List<int>();
            if (dataGridView1.CurrentCell == null || dataGridView1.SelectedCells.Count < 1) return tSelectIDX;
            List<DataGridViewCell> tSelectedCells = new List<DataGridViewCell>();
            foreach (DataGridViewCell cell in this.dataGridView1.SelectedCells)
            {
                tSelectedCells.Add(cell);
            }
            tSelectIDX = tSelectedCells.Select(x => x.RowIndex).Distinct().ToList();
            tSelectIDX.Sort();
            return tSelectIDX;
        }
        private void btnTag008_Click(object sender, EventArgs e)
        {
            List<int> tSelectIDX = GetSelectGridIDX();
            if (tSelectIDX.Count == 0) return;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {

                bool tCheck = dataGridView1.Rows[i].Cells["colCheck"].Value.ToString() == "T" ? true : false;
                if (!tCheck) continue;
                String_Text st = new String_Text();
                string tMarc = dataGridView1.Rows[i].Cells["marc"].Value.ToString();//= st.made_Ori_marc(tChange);
                int tTag008IDX = 0;

                if (tMarc.Length < 3) return;

                string result = string.Empty;

                List<string> tTagNum = new List<string>();   // 태그번호
                List<string> tField = new List<string>();    // 가변길이필드 저장

                // 특수기호 육안으로 확인하기 쉽게 변환
                tMarc = tMarc.Replace("", "▼");
                tMarc = tMarc.Replace("", "▲");
                tMarc = tMarc.Replace("￦", "\\");

                int startidx = 0;
                string[] data = tMarc.Substring(24).Split('▲'); // 리더부를 제외한 디렉터리, 가변길이필드 저장

                for (int a = 1; a < data.Length - 1; a++)
                {
                    tTagNum.Add(data[0].Substring(startidx, 3));
                    startidx += 12;
                    tField.Add(data[a] + "▲");
                }
                tTag008IDX = tTagNum.FindIndex(x => x == "008");
                if (tTag008IDX == -1) continue;
                string tData = tField[tTag008IDX];
                List<string> tListData = tData.ToCharArray().ToList().ConvertAll(x => x.ToString());
                if (tListData.Count < 40) continue;
                tListData[32] = cbTag008_32.Text;
                tField[tTag008IDX] = string.Join("", tListData);
                string tNewMarc = string.Empty;
                for (int j = 0; j < tTagNum.Count; j++)
                {
                    tNewMarc += string.Format("{0}\t{1}\t{2}\n", tTagNum[j], "  ", tField[j]);
                }
                dataGridView1.Rows[i].Cells["marc"].Value = st.made_Ori_marc(tNewMarc);
            }
            UTIL.MsgI("태그 일괄 적용 완료!");

        }

        private string[] Make_MarcArray(out string totalerrmsg)
        {
            totalerrmsg = string.Empty;
            String_Text st = new String_Text();
            string[] MarcArray = new string[dataGridView1.RowCount];
            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                if (dataGridView1.Rows[a].Cells["marc"].Value.ToString() == "" &&
                    dataGridView1.Rows[a].Cells["marc"].Value == null)
                    continue;

                if (dataGridView1.Rows[a].Cells["colCheck"].Value.ToString() != "T")
                    continue;

                string marc = dataGridView1.Rows[a].Cells["Marc"].Value.ToString().Replace("￦", "\\");
                marc = st.ConvertMarcType(marc, out string errmesage);
                if (errmesage.isEmpty() == false) totalerrmsg += (totalerrmsg.isEmpty() ? "\n" : "") + errmesage;
                MarcArray[a] = marc;
            }
            return MarcArray;
        }

        #region Grid 드래그 앤 드랍 함수 (사용하려면 dataGridView1의 AllowDrop 활성화해야함)

        private void chkBox_AllowDrop_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBox_AllowDrop.Checked)
            {
                chkBox_AllowDrop.Text = "표 드래그 앤 드롭 ON";
                dataGridView1.AllowDrop = true;
                dataGridView1.MouseDown += dataGridView1_MouseDown;
                dataGridView1.MouseMove += dataGridView1_MouseMove;
                dataGridView1.DragDrop += dataGridView1_DragDrop;
                dataGridView1.DragOver += dataGridView1_DragOver;
            }
            else
            {
                chkBox_AllowDrop.Text = "표 드래그 앤 드롭 OFF";
                dataGridView1.AllowDrop = false;
                dataGridView1.MouseDown -= dataGridView1_MouseDown;
                dataGridView1.MouseMove -= dataGridView1_MouseMove;
                dataGridView1.DragDrop -= dataGridView1_DragDrop;
                dataGridView1.DragOver -= dataGridView1_DragOver;
            }
        }

        Skill_Grid sg = new Skill_Grid();

        private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
        {
            sg.MouseDown(sender, e);
        }

        private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
        {
            sg.MouseMove(sender, e);
        }

        private void dataGridView1_DragDrop(object sender, DragEventArgs e)
        {
            sg.DragDrop(sender, e);
        }

        private void dataGridView1_DragOver(object sender, DragEventArgs e)
        {
            sg.DragOver(sender, e);
        }
        #endregion

        private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            String_Text st = new String_Text();

            int row = e.RowIndex;
            int col = dataGridView1.CurrentCell.ColumnIndex;

            if (col == 2 || col == 3 || col == 4 || col == 5 || col == 6 || col == 7 || col == 17)
            {
                if (dataGridView1.Rows[row].Cells["num"].Value == null)
                {
                    dataGridView1.Rows.RemoveAt(row);
                    return;
                }
                if (dataGridView1.Rows[row].Cells["marc"].Value == null)
                {
                    UTIL.MsgE("저장된 마크가 없습니다!");
                    return;
                }
                if (dataGridView1.Rows[row].Cells["marc"].Value.ToString() == "")
                {
                    UTIL.MsgE("저장된 마크가 없습니다!");
                    return;
                }

                string Marc = dataGridView1.Rows[row].Cells["marc"].Value.ToString();
                string TypeView = ConvertMarcType(Marc);
                string AddTag;

                if (col == 2 || col == 5 || col == 6 || col == 7)
                {
                    if (dataGridView1.Rows[row].Cells[2].Value == null) dataGridView1.Rows[row].Cells[2].Value = "";
                    if (dataGridView1.Rows[row].Cells[5].Value == null) dataGridView1.Rows[row].Cells[5].Value = "";
                    if (dataGridView1.Rows[row].Cells[6].Value == null) dataGridView1.Rows[row].Cells[6].Value = "";
                    if (dataGridView1.Rows[row].Cells[7].Value == null) dataGridView1.Rows[row].Cells[7].Value = "";

                    string L = dataGridView1.Rows[row].Cells[2].Value.ToString();
                    string V = dataGridView1.Rows[row].Cells[5].Value.ToString();
                    string C = dataGridView1.Rows[row].Cells[6].Value.ToString();
                    string F = dataGridView1.Rows[row].Cells[7].Value.ToString();

                    if (L != "")
                        L = string.Format("▼l{0}", L);

                    if (V != "")
                        V = string.Format("▼v{0}", V);

                    if (C != "")
                        C = string.Format("▼c{0}", C);

                    if (F != "")
                        F = string.Format("▼f{0}", F);

                    AddTag = string.Format("049\t  \t{0}{1}{2}{3}▲", L, V, C, F);

                    if (L == "" && V == "" && C == "" && F == "")
                    {
                        TypeView = st.RemoveTagNumber(TypeView, "049");
                    }
                    else
                    {
                        TypeView = AddTagInMarc(AddTag, TypeView);
                    }
                }
                if (col == 3 || col == 4 || col == 5)
                {
                    if (dataGridView1.Rows[row].Cells[3].Value == null) dataGridView1.Rows[row].Cells[3].Value = "";
                    if (dataGridView1.Rows[row].Cells[4].Value == null) dataGridView1.Rows[row].Cells[4].Value = "";
                    if (dataGridView1.Rows[row].Cells[5].Value == null) dataGridView1.Rows[row].Cells[5].Value = "";

                    string A = dataGridView1.Rows[row].Cells[3].Value.ToString();
                    string B = dataGridView1.Rows[row].Cells[4].Value.ToString();
                    string V = dataGridView1.Rows[row].Cells[5].Value.ToString();

                    if (A != "")
                    {
                        A = string.Format("▼a{0}", A);
                        TypeView = st.ChangeTagInMarc("056a", A, TypeView);
                    }

                    if (B != "")
                        B = string.Format("▼b{0}", B);

                    if (V != "")
                        V = string.Format("▼c{0}", V);

                    AddTag = string.Format("090\t  \t{0}{1}{2}▲", A, B, V);

                    if (A == "" && B == "" && V == "")
                    {
                        TypeView = st.RemoveTagNumber(TypeView, "090");
                    }
                    else
                    {
                        TypeView = AddTagInMarc(AddTag, TypeView);
                    }
                }
                if (col == 17)
                {
                    if (dataGridView1.Rows[row].Cells[3].Value == null) dataGridView1.Rows[row].Cells["price"].Value = "";
                    string tChangeValue = dataGridView1.Rows[row].Cells["price"].Value.ToString();

                    string tAddTag020 = string.Format("▼c{0}", tChangeValue);
                    string tAddTag950 = string.Format("▼b{0}", tChangeValue);

                    //TypeView = st.ChangeTagInMarc("950b", tAddTag950, TypeView);
                    //if (tChangeValue == "")
                    //{
                    //    TypeView = st.RemoveTagNumber(TypeView, "020c");
                    //    TypeView = st.RemoveTagNumber(TypeView, "950b");
                    //}
                    //else
                    //{
                    if (tChangeValue != "")
                    {
                        TypeView = st.ChangeTagInMarc("020c", tAddTag020, TypeView);
                        TypeView = st.ChangeTagInMarc("950b", tAddTag950, TypeView);
                    }
                }
                dataGridView1.Rows[row].Cells["marc"].Value = st.made_Ori_marc(TypeView);
            }
        }

        /// <summary>
        /// 한줄짜리 마크를 보기 쉬운 형태로 변환
        /// </summary>
        /// <param name="Marc">한줄짜리 마크</param>
        /// <returns></returns>
        string ConvertMarcType(string Marc)
        {
            if (Marc.Length < 3) return "";

            string result = "";

            List<string> TagNum = new List<string>();   // 태그번호 저장용
            List<string> Field = new List<string>();    // 가변길이필드 저장용

            // 특수기호 육안으로 확인하기 쉽게 변환
            Marc = Marc.Replace("", "▼");
            Marc = Marc.Replace("", "▲");
            Marc = Marc.Replace("￦", "\\");

            int StartIdx = 0;

            // 리더부를 제외한 디렉토리, 가변길이필드 저장
            string[] data = Marc.Substring(24).Split('▲');
            for (int a = 1; a < data.Length - 1; a++)
            {
                TagNum.Add(data[0].Substring(StartIdx, 3));
                StartIdx += 12;
                Field.Add(data[a] + "▲");
            }

            // List에 들어간 데이터를 메모장에 출력
            for (int a = 0; a < TagNum.Count; a++)
            {
                string res = TagNum[a];
                if (Field[a].IndexOf("▼") == -1)
                {
                    res += "\t  \t" + Field[a];
                }
                else
                {
                    string temp = Field[a].Insert(2, "\t");
                    res += "\t" + temp;
                }
                result += res + "\n";
            }
            return result;
        }

        /// <summary>
        /// 추가하고 싶은 태그를 뷰형태의 마크에 추가하는 함수.
        /// </summary>
        /// <param name="Tag">추가할 태그 (태그명\t지시기호\t태그내용)</param>
        /// <param name="TypeView">뷰형태의 마크</param>
        /// <returns></returns>
        string AddTagInMarc(string Tag, string TypeView)
        {
            if (Tag.Length < 3) return "";

            int TargetTagNum = Convert.ToInt32(Tag.Substring(0, 3));

            string[] SplitView = TypeView.Split('\n');
            List<string> View = new List<string>(SplitView);

            int ViewCount = 0;
            foreach (string LineMarc in View)
            {
                string LineTag = LineMarc.Substring(0, 3);
                int TagNum = 0;
                //Convert.ToInt32(LineTag);
                int.TryParse(LineTag, out TagNum);

                if (TargetTagNum == TagNum)
                {
                    View[ViewCount] = Tag;
                    break;
                }
                else if (TargetTagNum < TagNum)
                {
                    View.Insert(ViewCount, Tag);
                    break;
                }
                ViewCount++;
            }
            return string.Join("\n", View);
        }

        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            Skill_Grid sg = new Skill_Grid();
            sg.Excel_to_DataGridView(sender, e);
        }

        private void btn_PrintView_Click(object sender, EventArgs e)
        {
            if (cb_TextFont.SelectedIndex < 0)
            {
                UTIL.MsgE("글자체를 선택해주세요!");
                return;
            }
            Cnt = 0;
            isMorePage = false;
            printPreviewDialog1.Document = printDocument1;
            printPreviewDialog1.ShowDialog();
        }

        /// <summary>
        /// 행의 갯수
        /// </summary>
        int Cnt;

        /// <summary>
        /// 여러장 인쇄인지
        /// </summary>
        bool isMorePage;

        private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {
            Cnt = 0;
            isMorePage = false;
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            // A4 Size( 1169 x 827 in) ( 210 x 297 mm )
            float xPos = mmToInch(Convert.ToDouble(tb_Left.Text) - 4.5);
            float yPos = mmToInch(Convert.ToDouble(tb_Top.Text) - 3.5);
            float Width = mmToInch(Convert.ToDouble(tb_Width.Text));
            float Height = mmToInch(Convert.ToDouble(tb_Height.Text));

            int Garo = Convert.ToInt32(tb_Garo.Text);
            int Sero = Convert.ToInt32(tb_Sero.Text);
            int Total = Garo * Sero;
            int FontSize = Convert.ToInt32(tb_TextSize.Text);
            int NumSize = Convert.ToInt32(tb_NumSize.Text);

            float GaroGap = mmToInch(Convert.ToDouble(tb_GaroGap.Text));
            float SeroGap = mmToInch(Convert.ToDouble(tb_SeroGap.Text));

            List<string> GridData = PrintData();

            Pen ps = new Pen(Color.Red, 2);
            Font F = new Font(cb_TextFont.Text, FontSize);
            Font NumFont = new Font(cb_TextFont.Text, NumSize);

            StringFormat format = new StringFormat();
            if (chk_Alignment.Checked)
            {
                format.Alignment = StringAlignment.Center;
            }

            int startCount = Convert.ToInt32(tb_StartPosition.Text);
            if (isMorePage)
                startCount = 0;

            int GridCount = 0;
            for (int SeroCount = 0; SeroCount < Sero; SeroCount++)
            {
                float UxPos = xPos;
                for (int GaroCount = 0; GaroCount < Garo; GaroCount++)
                {
                    if (!chk_GuideLine.Checked)
                        e.Graphics.DrawRectangle(ps, UxPos, yPos, Width, Height);

                    if (Cnt >= dataGridView1.Rows.Count)
                        return;

                    if (GridCount >= startCount - 1)
                    {
                        if (chk_Alignment.Checked)
                            UxPos += mmToInch(8);

                        e.Graphics.DrawString(GridData[Cnt], F, Brushes.Black, UxPos + mmToInch(6), yPos + mmToInch(2), format);

                        if (!chk_Num.Checked)
                            e.Graphics.DrawString(
                                dataGridView1.Rows[Cnt].Cells["reg_num"].Value.ToString(),
                                NumFont,
                                Brushes.Black,
                                UxPos + mmToInch(6),
                                yPos + Width + mmToInch(4), format);
                        else
                            e.Graphics.DrawString(
                                dataGridView1.Rows[Cnt].Cells["reg_num"].Value.ToString(),
                                NumFont,
                                Brushes.Black,
                                UxPos + mmToInch(6),
                                yPos + mmToInch(FontSize * 0.35146 * 6) + mmToInch(2.5), format);

                        Cnt++;

                        if (chk_Alignment.Checked)
                            UxPos -= mmToInch(8);
                    }
                    UxPos += Width + GaroGap;
                    GridCount++;
                }
                if (GridCount % Total == 0)
                {
                    e.HasMorePages = true;
                    isMorePage = true;
                    return;
                }
                yPos += Height + SeroGap;
            }
        }

        #region PrintPage_Sub

        List<string> PrintData()
        {
            List<string> result = new List<string>();
            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                if (dataGridView1.Rows[a].Cells["colCheck"].Value.ToString() != "T")
                    continue;

                string classSymbol = dataGridView1.Rows[a].Cells["class_code"].Value.ToString();
                string authorSymbol = dataGridView1.Rows[a].Cells["author_code"].Value.ToString();
                string count = dataGridView1.Rows[a].Cells["copy"].Value.ToString();
                string vol = dataGridView1.Rows[a].Cells["volume"].Value.ToString();
                string fix = dataGridView1.Rows[a].Cells["prefix"].Value.ToString();
                string number = dataGridView1.Rows[a].Cells["reg_num"].Value.ToString();

                if (!chk_V.Checked)
                    vol = "";

                if (!chk_C.Checked)
                    count = "";

                if (!chk_Num.Checked)
                    number = "";

                string text = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}", fix, classSymbol, authorSymbol, count, vol, number);
                result.Add(text);
            }
            return result;
        }

        float mmToInch(int mm)
        {
            return mmToInch(Convert.ToDouble(mm));
        }

        /// <summary>
        /// 밀리미터를 인치 값으로 변환하여 반환
        /// </summary>
        /// <param name="mm">벼환시킬 밀리미터값</param>
        /// <returns>소수점이 포함된 인치값</returns>
        float mmToInch(double mm)
        {
            var col = mm / 25.4 * 100;
            float inch = (float)col;

            return inch;
        }

        #endregion

        private void btn_Bring_Click(object sender, EventArgs e)
        {
            Marc_Plan_PrintLabel printlabel = new Marc_Plan_PrintLabel(this);
            printlabel.Show();
        }

        #region Bring_Sub

        public void BringPringLabel(System.Windows.Forms.TextBox[] Box, string Font, bool[] ChkByC_V)
        {
            System.Windows.Forms.TextBox[] MyBox = { tb_Left, tb_Top, tb_Width, tb_Height, tb_GaroGap, tb_SeroGap, tb_Garo, tb_Sero, tb_TextSize };

            if (MyBox.Length != Box.Length)
                return;

            int count = 0;
            foreach (System.Windows.Forms.TextBox tb in MyBox)
            {
                tb.Text = Box[count].Text;
                count++;
            }

            cb_TextFont.SelectedItem = Font;

            chk_C.Checked = ChkByC_V[0];
            chk_V.Checked = ChkByC_V[1];
        }
        #endregion

        private void chk_Num_CheckedChanged(object sender, EventArgs e)
        {
            tb_NumSize.Enabled = chk_Num.Checked;
        }

        private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
        {
            if (e.Column.Name.Equals("num"))
            {
                //int a = int.Parse(e.CellValue1.ToString()), b = int.Parse(e.CellValue2.ToString());
                string tA = e.CellValue1.ToString();
                string tB = e.CellValue2.ToString();

                int tAValue = int.Parse(Regex.Replace(tA, @"[^0-9]", ""));
                int tBValue = int.Parse(Regex.Replace(tB, @"[^0-9]", ""));

                e.SortResult = tAValue.CompareTo(tBValue);
                //e.SortResult = a.CompareTo(b);
                e.Handled = true;
            }
        }

        private void btn_InputAutoCopy_Click(object sender, EventArgs e)
        {
            List<string> Condition = new List<string>();
            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                string midx = dataGridView1.Rows[a].Cells["midx"].Value.ToString();
                string reg_num = Regex.Replace(dataGridView1.Rows[a].Cells["reg_num"].Value.ToString(), @"\d", "");

                Condition.Add(midx + reg_num);
            }

            List<string> Condi = Condition.Distinct().ToList();
            List<string[]> Count = new List<string[]>();
            foreach (string s in Condi)
            {
                string[] Temp = { s, "1" };
                Count.Add(Temp);
            }

            int row = 0;
            foreach (string s in Condition)
            {
                for (int a = 0; a < Count.Count; a++)
                {
                    if (s == Count[a][0])
                    {
                        int cout = Convert.ToInt32(Count[a][1]);

                        if (cout > 1)
                            dataGridView1.Rows[row].Cells["copy"].Value = Count[a][1];

                        cout++;
                        Count[a][1] = cout.ToString();
                    }
                }
                row++;
            }
        }

        private void btn_InputColorFix_Click(object sender, EventArgs e)
        {
            string[,] CheckList = {
                { "부모", "0" }, { "육아", "0" }, { "유아교육", "0" }, { "유아 육아", "0" },
                { "어린이", "1" }, { "초등", "1" },
                { "유아", "2" },
                { "청소년", "3" }, { "중학", "3" }, { "고등학", "3" },
                { "전집", "4" }, { "컴퓨터", "4" }, { "종교", "4" }, { "문학론", "4" },
                { "소설", "5" }
            };

            Random r = new Random();
            int col = r.Next(10, 17);

            Color[] ColorList = { Color.Gray, Color.Orange, Color.Pink, Color.LightGreen, Color.MediumPurple, Color.LightSkyBlue };

            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                string WorkFix = dataGridView1.Rows[a].Cells["WorkFix"].Value.ToString();

                for (int b = 0; b < CheckList.GetLength(0); b++)
                {
                    if (WorkFix.IndexOf(CheckList[b, 0]) > -1)
                    {
                        dataGridView1.Rows[a].Cells[col].Style.BackColor = ColorList[Convert.ToInt32(CheckList[b, 1])];
                        break;
                    }
                }

            }
        }

        private void btn_ClassSymbol_Click(object sender, EventArgs e)
        {
            Marc_Plan_ClassSymbol mpc = new Marc_Plan_ClassSymbol(this);

            int[] count100 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            int[] count10 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            for (int a = 0; a < dataGridView1.Rows.Count; a++)
            {
                if (dataGridView1.Rows[a].Cells["class_code"].Value == null && dataGridView1.Rows[a].Cells["class_code"].Value.ToString() == "")
                    continue;

                string temp = dataGridView1.Rows[a].Cells["class_code"].Value.ToString();
                char number = temp[0];
                count100 = ReturnCount(count100, number);
                number = temp[1];
                count10 = ReturnCount(count10, number);
            }

            string[] Grid = { "", "", "", "" };
            for (int a = 0; a < count10.Length + 1; a++)
            {
                if (a == 10)
                {
                    Grid[0] = "총합";
                    Grid[1] = TotalCount(count100).ToString();
                    Grid[2] = "총합";
                    Grid[3] = TotalCount(count10).ToString();
                }
                else
                {
                    Grid[0] = String.Format("{0}00", a);
                    Grid[1] = count100[a].ToString();
                    Grid[2] = String.Format("{0}0", a);
                    Grid[3] = count10[a].ToString();
                }

                mpc.dataGridView1.Rows.Add(Grid);
            }
            mpc.Show();
        }

        int TotalCount(int[] Count)
        {
            int result = 0;
            foreach (int a in Count)
            {
                result += a;
            }
            return result;
        }

        int[] ReturnCount(int[] Count, char Target)
        {
            switch (Target)
            {
                case '0': Count[0]++; break;
                case '1': Count[1]++; break;
                case '2': Count[2]++; break;
                case '3': Count[3]++; break;
                case '4': Count[4]++; break;
                case '5': Count[5]++; break;
                case '6': Count[6]++; break;
                case '7': Count[7]++; break;
                case '8': Count[8]++; break;
                case '9': Count[9]++; break;
            }
            return Count;
        }

        private void btn_GearExcel_Click(object sender, EventArgs e)
        {
            if (dataGridView1.RowCount <= 0) return;

            Marc_Plan_GearExcel gear = new Marc_Plan_GearExcel();

            string[,] Content = new string[dataGridView1.RowCount, 6];

            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                Content[a, 0] = dataGridView1.Rows[a].Cells["num"].Value.ToString();
                Content[a, 1] = dataGridView1.Rows[a].Cells["reg_num"].Value.ToString();
                Content[a, 2] = dataGridView1.Rows[a].Cells["book_name"].Value.ToString();
                Content[a, 3] = dataGridView1.Rows[a].Cells["author"].Value.ToString();
                Content[a, 4] = dataGridView1.Rows[a].Cells["book_comp"].Value.ToString();
                Content[a, 5] = "";
            }
            gear.Content = Content;
            gear.ListName = btn_Select_List.Text;
            gear.Show();
        }

        private void tb_SearchChangeColor_Click(object sender, EventArgs e)
        {
            tb_SearchChangeColor.Text = "";
        }

        private void btn_ChangeColor_Click(object sender, EventArgs e)
        {
            if (dataGridView1.RowCount < 0) return;
            if (tb_SearchChangeColor.Text == "여러 개 입력시 , 로 구분") return;

            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                dataGridView1.Rows[a].Cells["search_tag2"].Style.BackColor = Color.White;
            }

            string[] SearchArray = tb_SearchChangeColor.Text.Split(',');

            for (int a = 0; a < dataGridView1.RowCount; a++)
            {
                string Target = dataGridView1.Rows[a].Cells["search_tag2"].Value.ToString();
                foreach (string t in SearchArray)
                {
                    if (t == "") continue;

                    if (Target.IndexOf(t.TrimStart().TrimEnd()) > -1)
                    {
                        dataGridView1.Rows[a].Cells["search_tag2"].Style.BackColor = Color.Yellow;
                        break;
                    }
                }
            }
        }

        private void btnInit_Click(object sender, EventArgs e)
        {
            mk_Grid(btn_Select_List.Text, this.date);
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            
        }

        private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
        {
            // 범위 입력받기
            string input = Microsoft.VisualBasic.Interaction.InputBox(
                "삭제할 행 범위를 입력하세요.\n예) 1~100 (1번부터 100번까지 삭제)",
                "행 범위 삭제",
                "",
                -1, -1);

            // 취소 또는 빈 입력
            if (string.IsNullOrWhiteSpace(input))
                return;

            try
            {
                // "1~100" 형식 파싱
                string[] parts = input.Split('~', '-');
                if (parts.Length != 2)
                {
                    UTIL.MsgE("올바른 형식으로 입력해주세요.\n예) 1~100");
                    return;
                }

                int startRow = int.Parse(parts[0].Trim());
                int endRow = int.Parse(parts[1].Trim());

                // 범위 검증
                if (startRow < 1 || endRow < 1)
                {
                    UTIL.MsgE("행 번호는 1 이상이어야 합니다.");
                    return;
                }

                if (startRow > endRow)
                {
                    UTIL.MsgE("시작 행 번호가 끝 행 번호보다 클 수 없습니다.");
                    return;
                }

                // 사용자 입력은 1부터 시작하지만, 인덱스는 0부터 시작하므로 -1
                int startIndex = startRow - 1;
                int endIndex = endRow - 1;

                // 범위가 데이터 범위를 벗어나는지 확인
                if (endIndex >= bs1.Count)
                {
                    UTIL.MsgE($"입력한 범위가 전체 데이터 수({bs1.Count})를 초과합니다.");
                    return;
                }

                // 삭제 확인
                string confirmMsg = string.Format("{0}번부터 {1}번까지 총 {2}개의 행을 삭제하시겠습니까?",
                    startRow, endRow, endRow - startRow + 1);
                if (UTIL.MsgQ(confirmMsg) == DialogResult.No)
                    return;

                // 뒤에서부터 삭제 (인덱스가 꼬이지 않도록)
                for (int i = endIndex; i >= startIndex; i--)
                {
                    if (i < bs1.Count)
                    {
                        bs1.RemoveAt(i);
                    }
                }

                UTIL.MsgI("삭제가 완료되었습니다.");
            }
            catch (FormatException)
            {
                UTIL.MsgE("숫자 형식으로 입력해주세요.\n예) 1~100");
            }
            catch (Exception ex)
            {
                UTIL.MsgE($"삭제 중 오류가 발생했습니다.\n{ex.Message}");
            }
        }

        private void btn_FillBlank_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow == null) return;
            int row = dataGridView1.CurrentRow.Index;
            string ISBN = dataGridView1.Rows[row].Cells["ISBN"].Value?.ToString();

            if (string.IsNullOrEmpty(ISBN))
            {
                UTIL.MsgE("ISBN이 존재하지않습니다!");
                return;
            }

            var fb = new Marc_FillBlank();
            for (int a = 0; a < bs1.Count; a++)
            {
                var item = bs1.List[a] as MarcPlanItem;
                if (item != null && (string.IsNullOrEmpty(item.Marc) || item.Marc.Length < 10))
                {
                    var fbItem = new FillBlankItem
                    {
                        Idx = a, // 그리드 순서를 인덱스로 사용
                        Isbn = item.Isbn ?? "",
                        BookName = item.BookName ?? "",
                        Author = item.Author ?? "",
                        Publisher = item.BookComp ?? "",
                        Price = item.Price
                    };
                    fb.InitFillBlank(fbItem);
                }
            }
            fb.ISBN = ISBN;
            if (fb.ShowDialog() == DialogResult.OK)
            {
                if (fb.FillBlankItems.Any(t => !string.IsNullOrEmpty(t.BookMarc)))
                {
                    foreach (var fbItem in fb.FillBlankItems)
                    {
                        if (string.IsNullOrEmpty(fbItem.BookMarc)) continue;

                        int targetIdx = fbItem.Idx;
                        if (targetIdx >= 0 && targetIdx < bs1.Count)
                        {
                            var item = bs1.List[targetIdx] as MarcPlanItem;
                            if (item != null)
                            {
                                item.Marc = fbItem.BookMarc;
                            }
                        }
                    }
                    bs1.ResetBindings(false);
                }
                else if (!string.IsNullOrEmpty(fb.SingleMarcResult))
                {
                    var item = bs1.Current as MarcPlanItem;
                    if (item != null)
                    {
                        item.Marc = fb.SingleMarcResult;
                        bs1.ResetCurrentItem();
                    }
                }
            }
        }
    }
}
