using SHDocVw;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UniMarc
{
    public partial class AddMarc2 : Form
    {
        Helper_DB db = new Helper_DB();
        String_Text st = new String_Text();
        Help008Tag tag008 = new Help008Tag();
        private string mOldMarc = string.Empty;
        Main m;
        public AddMarc2(Main _m)
        {
            InitializeComponent();
            m = _m;
        }

        private void AddMarc_Load(object sender, EventArgs e)
        {
            cb_SearchCol.SelectedIndex = 0;
            db.DBcon();
            TextReset();

            marcEditorControl1.db = this.db;
            marcEditorControl1.BookSaved += MarcEditorControl1_BookSaved;
            marcEditorControl1.CloseButton += (s1,e1)=> { this.Close(); };
            marcEditorControl1.SetButtonKolist(false);
            marcEditorControl1.SetButtonNext(false);
            marcEditorControl1.SetButtonPrev(false);
        }
        public void SetKolisValueApply(string marc)
        {
            this.marcEditorControl1.SetMarcString(marc);
        }
        private void MarcEditorControl1_BookSaved(object sender, MarcEditorControl.BookSavedEventArgs e)
        {
            string tag056 = Tag056(e.DBMarc, e.Param);
            string date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            string orimarc = st.made_Ori_marc(e.DBMarc).Replace(@"\", "￦");

            if (!isMustTag(orimarc))
            {

                return;
            }
            var MarcText = e.DBMarc;
            string midx = this.lbl_Midx;
            string[] BookData = GetBookData(MarcText);
            bool IsCoverDate = false;

            if (e.Param.SaveDate != "")
            {
                // 마지막 수정일로부터 2일이 지났는지, 마지막 저장자가 사용자인지 확인
                TimeSpan sp = CheckDate(e.Param.SaveDate, date);
                IsCoverDate = IsCoverData(sp.Days, e.Param.User);
                //if (IsCoverDate)
                //    etc2.Text = etc2.Text.Replace(SaveData[0], date);
            }
            //else
            //    etc2.Text += string.Format("{0}\t{1}\n", date, mUserName);
            string Table = "Marc";
            bool isUpdate;
            if (lbl_Midx != "")
                isUpdate = true;
            else
                isUpdate = false;

            var grade = int.Parse(e.Param.Grade);

            if (isUpdate)
                UpdateMarc(Table, midx, orimarc, grade, tag056, date, IsCoverDate,e.Param);
            else
                InsertMarc(Table, BookData, orimarc, grade, tag056, date, e.Param);

            MessageBox.Show("저장되었습니다.", "저장");
        }


        private void tb_ISBN_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Enter)
                return;

            TextReset();

            string SearchText = tb_Search.Text;
            string SearchCol = cb_SearchCol.SelectedItem.ToString();
            var mcs = new MarcCopySelect2(this);
            mcs.Init(SearchCol, SearchText);
            mcs.Show();
        }

        /// <summary>
        /// ISBN 검색후 특정 마크 선택시 현재폼에 적용시키는 폼
        /// </summary>
        /// <param name="Marc">뷰형태 마크데이터</param>
        /// <param name="ISBN">ISBN</param>
        /// <param name="GridData">
        /// 0:idx     <br></br>
        /// 1:compidx <br></br>
        /// 2:user    <br></br>
        /// 3:date    <br></br>
        /// 4:grade   <br></br>
        /// 5:tag008  <br></br>
        /// 6:LineMarc</param>
        public void SelectMarc_Sub(string Marc, string ISBN, string[] GridData)
        {
            this.marcEditorControl1.LoadBookData(Marc, new MacEditorParameter
            {
                ISBN13 = ISBN,
                SaveDate = string.Format("[{0}] [{1}]", GridData[2], GridData[3]),
                Grade = GridData[4],
                Remark1 = string.Empty,
                Remark2 = string.Empty,
                NewMake = true
            });
            mOldMarc = GridData[6];
            lbl_Midx = GridData[0];
        }
        string lbl_Midx = "";


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

        private void btn_Empty_Click(object sender, EventArgs e)
        {
            TextReset();

        }

        /// <summary>
        /// 전체 초기화
        /// </summary>
        /// <param name="isDelete">탭 컨트롤에서 사용할 경우 false</param>
        public void TextReset(bool isDelete = true)
        {
            if (isDelete)
            {
                marcEditorControl1.LoadBookData(string.Empty, new MacEditorParameter
                {
                    ISBN13 = string.Empty,
                    SaveDate = string.Empty,
                    Remark1 = string.Empty,
                    Remark2 = string.Empty,
                    NewMake=true,
                });
            }


        }

        string TextResetSub()
        {
            // 입력일자 (00-05)
            // 발행년유형 (6)
            // 발행년1 (07-10)
            // 발행년2 (11-14)
            // 발행국 (15-17)

            // 삽화표시 (18-21)
            // 이용대상자수준 (22) v
            // 개별자료형태 (23) v
            // 내용형식1 (24) v
            // 내용형식2 (25) v

            // 한국대학부호 (26-27)
            // 수정레코드 (28)
            // 회의간행물 (29) c
            // 기념논문집 (30) c
            // 색인 (31)

            // 목록전거 (32)
            // 문학형식 (33) v
            // 전기 (34) v
            // 언어 (35-37) v
            // 한국정부기관부호 (38-39)
            string yyMMdd = DateTime.Now.ToString("yyMMdd");
            string yyyy = DateTime.Now.ToString("yyyy");
            string Empty_008 = yyMMdd + "s" + yyyy + "                  000   kor  ▲";
            string Empty_text = string.Format(
                $"008\t  {Empty_008.Replace("▲", "")}" +
                "020\t  \t▼a▼c▲\n" +
                "056\t  \t▼a▼2▲\n" +
                "100\t  \t▼a▲\n" +
                "245\t  \t▼a▼d▲\n" +
                "260\t  \t▼b▲\n" +
                "300\t  \t▼a▼c▲\n" +
                "653\t  \t▼a▲\n" +
                "700\t  \t▼a▲\n" +
                "950\t  \t▼b▲\n");

            this.marcEditorControl1.SetRemark(string.Empty, string.Empty);
            return Empty_text;
        }

    
        #region SaveSub

        /// <summary>
        /// 마크DB에 UPDATE해주는 함수
        /// </summary>
        /// <param name="Table">테이블 이름</param>
        /// <param name="MarcIndex">마크 인덱스 번호</param>
        /// <param name="oriMarc">한줄짜리 마크</param>
        /// <param name="grade">마크 등급</param>
        /// <param name="tag056">분류기호</param>
        /// <param name="date">저장시각 yyyy-MM-dd HH:mm:ss</param>
        /// <param name="IsCovertDate">덮어씌울지 유무</param>
        void UpdateMarc(string Table, string MarcIndex, string oriMarc, int grade, string tag056, string date, bool IsCovertDate, MacEditorParameter param)
        {
            string[] EditTable =
            {
                "compidx", "marc", "marc_chk","marc1", "marc_chk1", "비고1",
                "비고2", "division", "008tag", "date", "user",
                "grade"
            };
            string[] EditColumn =
            {
                PUB.user.CompanyIdx, oriMarc, "1",mOldMarc, "0", param.Remark1,
                param.Remark2, tag056, param.text008, date, PUB.user.UserName,
                grade.ToString()
            };
            string[] SearchTable = { "idx", "compidx" };
            string[] SearchColumn = { MarcIndex, PUB.user.CompanyIdx };

            //int marcChk = subMarcChk(Table, MarcIndex);
            //if (IsCovertDate)
            //    marcChk--;

            //switch (marcChk)
            //{
            //    case 0:
            //        EditTable[1] = "marc1";
            //        EditTable[2] = "marc_chk1";
            //        EditTable[3] = "marc_chk";
            //        break;
            //    case 1:
            //        EditTable[1] = "marc2";
            //        EditTable[2] = "marc_chk2";
            //        EditTable[3] = "marc_chk1";
            //        break;
            //    case 2:
            //        EditTable[1] = "marc";
            //        EditTable[2] = "marc_chk";
            //        EditTable[3] = "marc_chk2";
            //        break;
            //    default:
            //        EditTable[1] = "marc";
            //        EditTable[2] = "marc_chk";
            //        EditTable[3] = "marc_chk2";
            //        break;
            //}
            string UpCMD = db.More_Update(Table, EditTable, EditColumn, SearchTable, SearchColumn);
            PUB.log.Add("ADDMarcUPDATE", string.Format("{0}({1}) : {2}", PUB.user.UserName, PUB.user.CompanyIdx, UpCMD.Replace("\r", " ").Replace("\n", " ")));
            Helper_DB.ExcuteNonQuery(UpCMD);
        }

        /// <summary>
        /// 마크DB에 INSERT해주는 함수
        /// </summary>
        /// <param name="Table">테이블 이름</param>
        /// <param name="BookData">0:ISBN 1:서명 2:저자 3:출판사 4:정가</param>
        /// <param name="oriMarc">한줄짜리 마크</param>
        /// <param name="grade">마크 등급</param>
        /// <param name="tag056">분류기호</param>
        /// <param name="date">저장시각 yyyy-MM-dd HH:mm:ss</param>
        void InsertMarc(string Table, string[] BookData, string oriMarc, int grade, string tag056, string date, MacEditorParameter param)
        {
            string[] InsertTable =
            {
                "ISBN", "서명", "저자", "출판사", "가격",
                "marc", "비고1", "비고2", "grade", "marc_chk",
                "user", "division", "008tag", "date", "compidx"
            };
            string[] InsertColumn =
            {
                BookData[0], BookData[1], BookData[2], BookData[3], BookData[4],
                oriMarc, param.Remark1, param.Remark2, grade.ToString(), "1",
                PUB.user.UserName, tag056, param.text008, date, PUB.user.CompanyIdx
            };

            string InCMD = db.DB_INSERT(Table, InsertTable, InsertColumn);
            PUB.log.Add("ADDMarcINSERT", string.Format("{0}({1}) : {2}", PUB.user.UserName, PUB.user.CompanyIdx, InCMD.Replace("\r", " ").Replace("\n", " ")));
            Helper_DB.ExcuteNonQuery(InCMD);
        }

        /// <summary>
        /// 마크 저장시 사용하며, 마지막 수정일과 수정자를 가져와 덮어씌울지 백업데이터를 만들지 구분
        /// </summary>
        /// <param name="TimeSpanDaysValue">저장할 마크의 마지막 수정일</param>
        /// <param name="user">저장할 마크의 마지막 수정자</param>
        /// <returns>마지막 수정일로부터 2일이 지나지 않고, 마지막 수정자와 해당 유저가 동일 할 경우 True 반환</returns>
        private bool IsCoverData(int TimeSpanDaysValue, string user)
        {
            if (TimeSpanDaysValue < -1)
                return false;
            if (user != PUB.user.UserName)
                return false;
            return true;
        }

        private TimeSpan CheckDate(string LastDate, string SaveDate)
        {
            DateTime Last = Convert.ToDateTime(LastDate);
            DateTime Save = Convert.ToDateTime(SaveDate);

            return Last - Save;
        }

       

        /// <summary>
        /// 필수태그 검사
        /// </summary>
        /// <param name="orimarc">한줄짜리 마크</param>
        /// <returns>필수태그 없을시 false 반환</returns>
        private bool isMustTag(string orimarc)
        {
            string[] SearchTag = { "056a", "0562", "245a", "245d", "260a", "260c", "300a", "300c", "653a" };
            string[] Tag = st.Take_Tag(orimarc, SearchTag);

            int count = 0;
            string msg = "";
            bool isTag = true;
            foreach (string tag in Tag)
            {
                if (tag == "")
                {
                    msg += SearchTag[count] + " ";
                    isTag = false;
                }
                count++;
            }
            if (!isTag)
            {
                MessageBox.Show(msg + "태그가 없습니다.");
                return false;
            }

            bool is1XX = false;
            string[] AuthorTag = { "100a", "110a", "111a" };
            Tag = st.Take_Tag(orimarc, AuthorTag);
            foreach (string author in Tag)
            {
                if (author != "")
                    is1XX = true;
            }
            if (!is1XX)
            {
                MessageBox.Show("기본표목이 존재하지않습니다.");
                return false;
            }

            bool is7XX = false;
            AuthorTag[0] = "700a";
            AuthorTag[1] = "710a";
            AuthorTag[2] = "711a";
            Tag = st.Take_Tag(orimarc, AuthorTag);

            foreach (string author in Tag)
            {
                if (author != "")
                    is7XX = true;
            }

            if (!is7XX)
            {
                MessageBox.Show("부출표목이 존재하지않습니다.");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 관련 도서 정보를 가져옴
        /// </summary>
        /// <param name="ViewMarc">뷰형태의 마크</param>
        /// <returns>0:ISBN 1:서명 2:저자 3:출판사 4:정가</returns>
        string[] GetBookData(string ViewMarc)
        {
            // ISBN, BookName, Author, BookComp, Price
            string[] result = { "", "", "", "", "" };
            bool IsISBN = false;
            string[] TargetArr = ViewMarc.Split('\n');
            foreach (string Target in TargetArr)
            {
                string[] tmp = Target.Replace("▲", "").Split('\t');
                // 0:ISBN 4:Price
                if (tmp[0] == "020" && !IsISBN)
                {
                    IsISBN = true;
                    result[0] = GetMiddelString(tmp[2], "▼a", "▼");
                    result[4] = GetMiddelString(tmp[2], "▼c", "▼");
                }

                // 2:Author
                if (tmp[0] == "100")
                    result[2] = GetMiddelString(tmp[2], "▼a", "▼");
                else if (tmp[0] == "110")
                    result[2] = GetMiddelString(tmp[2], "▼a", "▼");
                else if (tmp[0] == "111")
                    result[2] = GetMiddelString(tmp[2], "▼a", "▼");

                // 1:BookName
                if (tmp[0] == "245")
                    result[1] = GetMiddelString(tmp[2], "▼a", "▼");

                // 3:BookComp
                if (tmp[0] == "300")
                    result[3] = GetMiddelString(tmp[2], "▼b", "▼");
            }

            return result;
        }

        string Tag056(string marc,MacEditorParameter param)
        {
           // string marc = richTextBox1.Text;
            string[] temp = marc.Split('\n');
            List<string> target = temp.ToList();
            bool isEight = false;
            bool eight_chk = false;
            string tag056 = string.Empty;
            int count = 0;

            for (int a = 0; a < target.Count - 1; a++)
            {
                string[] tmp = target[a].Split('\t');
                string tag = tmp[0];
                if (tag == "") break;
                int eight = Convert.ToInt32(tag.Substring(0, 3));
                if (eight == 008)
                {
                    count = a;
                    eight_chk = true;
                    isEight = true;
                }
                else if (eight > 008 && !eight_chk)
                {
                    count = a;
                    eight_chk = true;
                }
                if (tag == "056")
                    tag056 = GetMiddelString(tmp[2], "▼a", "▼");
            }
            if (!isEight)
                target.Insert(count, string.Format("{0}\t{1}\t{2}▲", "008", "  ", param.text008));

            //richTextBox1.Text = string.Join("\n", target.ToArray());
            return tag056;
        }

        

        /// <summary>
        /// 문자와 문자사이의 값 가져오기
        /// </summary>
        /// <param name="str">대상 문자열</param>
        /// <param name="begin">시작 문자열</param>
        /// <param name="end">마지막 문자열</param>
        /// <param name="TagNum">불러올 태그 번호</param>
        /// <returns>문자 사이값</returns>
        public string GetMiddelString(string str, string begin, string end, string TagNum = "")
        {
            string result = "";

            if (string.IsNullOrEmpty(str) || str == "")
                return result;

            int count = 0;
            bool loop = false;

            for (int a = count; a < str.Length; a++)
            {
                count = str.IndexOf(begin);
                if (count > -1)
                {
                    str = str.Substring(count + begin.Length);
                    if (loop)
                        // 여러 태그들 구분을 지어줌.
                        result += "▽";

                    if (str.IndexOf(end) > -1)
                        result += str.Substring(0, str.IndexOf(end));
                    else
                        result += str;

                    result = TrimEndGubun(result, TagNum);
                }
                else
                    break;

                loop = true;
            }

            return result;
        }

        string TrimEndGubun(string str, string TagNum)
        {
            char[] gu = { '.', ',', ':', ';', '/', ' ' };
            if (TagNum == "300" || TagNum == "300a")
            {
                str = str.Trim();
                if (TagNum == "300a")
                {
                    gu = new char[] { '.', ',', '=', ':', ';', '/', '+', ' ' };
                    for (int i = 0; i < gu.Length; i++)
                    {
                        str = str.TrimEnd(gu[i]);
                    }
                }

                if (str.Contains("ill."))
                    return str;
                if (str.Contains("p."))
                    return str;
            }

            if (TagNum == "710" || TagNum == "910")
                return str;


            if (TagNum == "245") gu = new char[] { '.', ':', ';', '/', ' ' };
            if (TagNum == "245a") gu = new char[] { '.', ',', '=', ':', ';', '/', ' ' };
            for (int i = 0; i < gu.Length; i++)
            {
                str = str.TrimEnd(gu[i]);
            }
            //foreach (char gubun in gu)
            //{
            //    if (str.Length < 1) continue;
            //    if (str[str.Length - 1] == gubun)
            //    {
            //        str = str.Remove(str.Length - 1);
            //        str = str.Trim();
            //    }
            //}

            return str;
        }
        #endregion


        private void Btn_SearchKolis_Click(object sender, EventArgs e)
        {
            AddMarc_FillBlank af = new AddMarc_FillBlank(this);
            af.Show();
        }


    }
}
