using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AR;
using SATOPrinterAPI;

namespace Project.Dialog
{
    public partial class fLoaderInfo : Form
    {
        string PrintPos = "";

        public fLoaderInfo(List<string> errlist)
        {
            InitializeComponent();
            PUB.flag.set(eVarBool.FG_WAIT_LOADERINFO, true, "_LOAD");
            this.FormClosed += FLoaderInfo_FormClosed;
            this.lstErrmsg.Items.Clear();
            this.WindowState = FormWindowState.Maximized;
            this.label9.Text = "1D(11)";
            this.label10.Text = "QR(1)";
            this.label11.Text = "DataMatrix(2)";
            if (errlist != null)
            {

                foreach (var item in errlist)
                    AddErrorMessage(item);
            }
            if (PUB.Result.vModel.IgnoreBatch) tbBatch.Enabled = false;
            if (PUB.Result.vModel.IgnorePartNo) tbpartno.Enabled = false;
            linkLabel7.Enabled = tbpartno.Enabled;
            button4.Enabled = tbpartno.Enabled;
            btPartChk.Enabled = tbpartno.Enabled;
            lnkBatch.Enabled = tbBatch.Enabled;
        }

        void AddErrorMessage(string msg)
        {
            if (this.lstErrmsg.InvokeRequired)
            {
                this.lstErrmsg.BeginInvoke(new Action(() =>
                {
                    //동일한 태그를 가진 항목이 존재하는가?
                    if (lstErrmsg.FindString(msg) < 0)
                        lstErrmsg.Items.Add(string.Format("{0}", msg));
                }));
            }
            else
            {
                //동일한 태그를 가진 항목이 존재하는가?
                if (lstErrmsg.FindString(msg) < 0)
                    lstErrmsg.Items.Add(string.Format("{0}", msg));
            }
        }

        private void FLoaderInfo_FormClosed(object sender, FormClosedEventArgs e)
        {
            //이미지해제  210329
            if (this.ivF.Image != null)
            {
                this.ivF.Image.Dispose();
                this.ivF.Image = null;
            }

            PUB.flag.set(eVarBool.FG_WAIT_LOADERINFO, false, "_CLOSE");

            PUB.Result.ItemDataC.VisionData.PropertyChanged -= VisionData_PropertyChanged;

            //사용자가 정보를 정확히 입력하지 않고 닫았다
            if (PUB.Result.ItemDataC.VisionData.Confirm == false)
            {
                if (PUB.sm.Step == eSMStep.RUN)
                {
                    PUB.Result.SetResultMessage(eResult.OPERATION, eECode.INCOMPLETE_LOADERDATA, eNextStep.PAUSE, 1);
                }
            }
        }

        private void fLoaderInfo_Load(object sender, EventArgs e)
        {
            //현재 바코드가 읽었단 자료를 모두 표시한다.
            var item = PUB.Result.ItemDataC;
            this.tbRID.Text = item.VisionData.RID;
            this.tbRID0.Text = item.VisionData.RID0;
            NewReelId = item.VisionData.RIDNew;

            lvbcdList.Columns.Clear();
            lvbcdList.Columns.Add("각도", 60);
            lvbcdList.Columns.Add("값", 250);
            lvbcdList.Columns.Add("*", 45);


            //sid전환기능은  옵션의  상태값에  연결
            if (PUB.sm.Step != eSMStep.IDLE)
                btSidConv.Enabled = VAR.BOOL[eVarBool.Opt_SIDConvert];

            //if (Pub.Result.JobType == "13" )
            //{
            //	if (Pub.Result.ItemData[1].VisionData.SID.StartsWith("103"))
            //	{
            //		tbSID.Text = Pub.Result.ItemData[1].VisionData.SID;
            //	}
            //	else
            //	{
            //		var msg = $"13작업이나 입력된 SID가 103이 아니여서 적용하지 않습니다. sid:{Pub.Result.ItemData[1].VisionData.SID}";
            //		Pub.AddSystemLog(Application.ProductVersion, "LoaderInfo", msg);
            //		Pub.log.AddAT(msg);
            //	}
            //}
            //else 
            //{
            tbSID.Text = item.VisionData.SID;
            lbSID0.Text = item.VisionData.SID0;

            if (lbSID0.Text.isEmpty() == false)
                lbSID0.Tag = lbSID0.Text;

            tbVLOT.Text = item.VisionData.VLOT;

            //수량메뉴얼입력칸


            if (VAR.BOOL[eVarBool.Opt_UserQtyRQ])
            {
                if (item.VisionData.QTYRQ == true)
                {
                    //수동입력이나 바코드에서 RQ값이 들어있는 상태이니 그것을 사용한다.
                    //lock (Pub.Result.ItemData[1].VisionData.barcodelist)
                    {
                        var rqBcd = item.VisionData.barcodelist.Where(t => t.Value.Data.StartsWith("RQ")).FirstOrDefault();
                        if (rqBcd.Value != null)
                        {
                            var newqty = rqBcd.Value.Data.Substring(2).Trim();
                            PUB.log.Add($"Quantity updated {tbQTY.Text}->{newqty}");
                            tbQTY.Text = newqty;
                        }
                        else
                        {
                            PUB.log.AddAT("RQ was set but the value is not in the code list, quantity will not be filled");
                        }
                    }



                }
                else
                {
                    //Clear quantity value for manual input case
                    PUB.log.Add($"Quantity updated {tbQTY.Text}-> (cleared for manual input)");
                    tbQTY.Text = string.Empty;
                }
            }
            else
            {
                PUB.log.Add($"Quantity updated {tbQTY.Text}->{item.VisionData.QTY}");
                tbQTY.Text = item.VisionData.QTY;
            }

            lbQTY0.Text = item.VisionData.QTY0;
            tbMFG.Text = item.VisionData.MFGDATE;
            tbVName.Text = item.VisionData.VNAME;
            tbpartno.Text = item.VisionData.PARTNO;

            TbCustCode.Text = item.VisionData.CUSTCODE; //210317
            tbCustName.Text = item.VisionData.CUSTNAME;
            tbBatch.Text = item.VisionData.BATCH;
            tbQtyMax.Text = item.VisionData.QTYMAX;

            //Label position info display - 210127 -- delete(220706)
            //DisplayLabelPos(PUB.Result.ItemData[1].VisionData.LabelPositionData);

            //Print info display
            this.PrintPos = item.VisionData.PrintPositionData;
            if (PUB.flag.get(eVarBool.Opt_DisablePrinter)) this.PrintPos = "8";
            if (this.PrintPos.isEmpty() && item.VisionData.SID.isEmpty() == false)
            {
                //If print position is empty, query server to find data - 231005
                var taresult = new DataSet1TableAdapters.K4EE_Component_Reel_ResultTableAdapter();
                this.PrintPos = taresult.GetPrintPosition(AR.SETTING.Data.McName, item.VisionData.SID);
            }
            DisplayPrintPos(this.PrintPos);

            //Image display 210121
            this.ivF.Shapes.Clear();
            this.ivR.Shapes.Clear();
            if (item.VisionData.imageF != null)
            {
                //이미지복사해서사용 210329
                var keyImage = item.VisionData.imageF.Clone();
                this.ivF.Image = keyImage;
            }
            if (item.VisionData.imageR != null)
            {
                //이미지복사해서사용 210329
                var keyImage = item.VisionData.imageR.Clone();
                this.ivR.Image = keyImage;
            }
            this.lvbcdList.Items.Clear();

            //키엔스로부터 읽은 바코드 목록을 표시한다(우측)
            func_displaybcdlist();

            if (ivF.Image != null)
                ivF.ZoomFit();

            if (ivR.Image != null)
                ivR.ZoomFit();

            selectInput(this.tbRID);

            //자동판단데이터 확인; (101-103d우선처리)
            //이제 모든 sid변환은 1,3컬럼만 사용한다, 22-01-04
            if (PUB.Result.JobType2 == "13" && tbSID.Text.StartsWith("10")) func_sidconv(true);

            //기본값 적용 220712
            if (tbVName.Text.isEmpty())
                if (PUB.Result.vModel.Def_Vname.isEmpty() == false)
                    tbVName.Text = PUB.Result.vModel.Def_Vname;

            if (tbMFG.Text.isEmpty())
                if (PUB.Result.vModel.Def_MFG.isEmpty() == false)
                    tbMFG.Text = PUB.Result.vModel.Def_MFG;

            //자동완료이며, 사용자 확인이 off된상태, 수량입력도 false 된 상태여야함
            if (VAR.BOOL[eVarBool.Option_AutoConf] &&
                VAR.BOOL[eVarBool.Opt_UserConfim] == false &&
                VAR.BOOL[eVarBool.Opt_UserQtyRQ] == false &&
                PUB.Result.JobFirst == false)
            {
                //자료가 모두 있는지 확인한다.
                tmAutoConfirm.Start();
            }


            item.VisionData.PropertyChanged += VisionData_PropertyChanged;
        }

        delegate void UpdateTextHandler(Control ctrl, string value);
        public void UpdateText(Control ctrl, string value)
        {
            if (ctrl is Label || ctrl is TextBox)
            {
                if (ctrl.InvokeRequired)
                {
                    ctrl.BeginInvoke(new UpdateTextHandler(UpdateText), new object[] { ctrl, value });
                }
                else if (ctrl is Label)
                    ((Label)ctrl).Text = value;
                else if (ctrl is TextBox)
                    ((TextBox)ctrl).Text = value;
            }

        }

        private void VisionData_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //값이 바뀌었으나 현재 값이 입력되지 않았따면 처리해준다. 220712
            var item = PUB.Result.ItemDataC;

            if (e.PropertyName.Equals("QTY0") && lbQTY0.Text.isEmpty())
                UpdateText(lbQTY0, item.VisionData.QTY0);

            if (e.PropertyName.Equals("QTY") && this.tbQTY.Text.isEmpty())
                UpdateText(tbQTY, item.VisionData.QTY);

            if (e.PropertyName.Equals("MFGDATE") && tbMFG.Text.isEmpty())
                UpdateText(tbMFG, item.VisionData.MFGDATE);

            if (e.PropertyName.Equals("VNAME") && tbVName.Text.isEmpty())
                UpdateText(tbVName, item.VisionData.VNAME);

            if (e.PropertyName.Equals("PARTNO") && tbpartno.Text.isEmpty())
                UpdateText(tbpartno, item.VisionData.PARTNO);

            if (e.PropertyName.Equals("CUSTCODE") && TbCustCode.Text.isEmpty())
                UpdateText(TbCustCode, item.VisionData.CUSTCODE); //210317

            if (e.PropertyName.Equals("CUSTNAME") && tbCustName.Text.isEmpty())
                UpdateText(tbCustName, item.VisionData.CUSTNAME);

            if (e.PropertyName.Equals("SID") && tbSID.Text.isEmpty())
                UpdateText(tbSID, item.VisionData.SID);

            if (e.PropertyName.Equals("RID") && tbRID.Text.isEmpty())
                UpdateText(tbRID, item.VisionData.RID);

            if (e.PropertyName.Equals("RID0") && tbRID0.Text.isEmpty())
                UpdateText(tbRID0, item.VisionData.RID0);

            if (e.PropertyName.Equals("SID0") && lbSID0.Text.isEmpty())
                UpdateText(lbSID0, item.VisionData.SID0);

            if (e.PropertyName.Equals("VLOT") && tbVLOT.Text.isEmpty())
                UpdateText(tbVLOT, item.VisionData.VLOT);
        }

        void func_displaybcdlist()
        {
            var itemc = PUB.Result.ItemDataC;
            var angok = itemc.VisionData.BaseAngle(out string msg, out Class.KeyenceBarcodeData bcd);
            lock (itemc.VisionData.barcodelist)
            {
                var no = 1;
                lvbcdList.Items.Clear();    //기존꺼 삭제
                foreach (var bcddata in itemc.VisionData.barcodelist)
                {
                    var item = bcddata.Value;
                    var lv = this.lvbcdList.Items.Add(item.Angle.ToString("N1"));
                    lv.SubItems.Add(item.Data);
                    lv.SubItems.Add(item.barcodeSymbol + item.barcodeSource);
                    //.SubItems.Add(item.barcodeSource);
                    //lv.SubItems.Add(item.CenterPX.X.ToString());
                    //lv.SubItems.Add(item.CenterPX.Y.ToString());
                    if (item.RegExConfirm)
                    {
                        if (item.RefExApply)
                            lv.ForeColor = Color.Blue;
                        else
                            lv.ForeColor = Color.Black;
                    }
                    else lv.ForeColor = Color.DimGray;

                    if (item.barcodeSymbol == "1") lv.BackColor = Color.Gold;
                    else if (item.barcodeSymbol == "2") lv.BackColor = Color.Lime;
                    else lv.BackColor = Color.WhiteSmoke;

                    //회전에 사용할 데이터라면 체크를 해준다.
                    if (angok && bcd.Data == item.Data)
                    {
                        if (this.lvbcdList.CheckedItems.Count == 0)
                            lv.Checked = true;
                    }
                    else lv.Checked = false;

                    //vertext 표시
                    var vt = item.vertex;
                    if (vt.Length == 4)
                    {
                        Color lcolor = no % 2 == 0 ? Color.Tomato : Color.Lime;
                        if (item.barcodeSource == "F")
                        {
                            ivF.AddShapeLine(vt[0], vt[1], lcolor);
                            ivF.AddShapeLine(vt[1], vt[2], lcolor);
                            ivF.AddShapeLine(vt[2], vt[3], lcolor);
                            ivF.AddShapeLine(vt[3], vt[0], lcolor);
                            ivF.AddShapeText(vt[0], no.ToString(), Color.Black); //210312
                        }
                        else
                        {
                            ivR.AddShapeLine(vt[0], vt[1], lcolor);
                            ivR.AddShapeLine(vt[1], vt[2], lcolor);
                            ivR.AddShapeLine(vt[2], vt[3], lcolor);
                            ivR.AddShapeLine(vt[3], vt[0], lcolor);
                            ivR.AddShapeText(vt[0], no.ToString(), Color.Black); //210312
                        }

                    }

                    //가장우측상단에 번호를 표시한다.


                    no += 1;
                }
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        string TagStr = string.Empty;
        void selectInput(Control c)
        {
            TagStr = string.Empty;
            if (c is TextBox)
            {
                var tb = c as TextBox;
                TagStr = tb.Tag.ToString();
            }
            else if (c is Label)
            {
                var lb = c as Label;
                TagStr = lb.Tag.ToString();
            }

            //동일태그를 가진 textbox 의 배경색을 업데이트한다
            foreach (Control tb in groupBox2.Controls)
            {
                if (tb is TextBox)
                {
                    if (tb.Tag.ToString() == TagStr)
                    {
                        tb.BackColor = Color.SkyBlue;
                    }
                    else tb.BackColor = SystemColors.Control;
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //if (this.listView1.FocusedItem == null)
            //{
            //	Util.MsgE("입력할 바코드 값을 먼저 선택하세요");
            //	return;
            //}
            if (this.TagStr.isEmpty())
            {
                UTIL.MsgE("Please click the field to enter data first");
                return;
            }
            var lvitem = this.lvbcdList.FocusedItem;
            if (lvitem == null) return;

            var lvValue = lvitem.SubItems[1].Text.Trim();
            if (lvValue.isEmpty())
            {
                UTIL.MsgE("The selected data has no value\n\nPlease select other data");
                return;
            }

            //선택자료가 ; 으로 분류가능하면 추가로 팝업
            if (lvValue.Split(';').Length > 1)
            {
                var ff = new Dialog.fSelectDataList(lvValue.Split(';'));
                if (ff.ShowDialog() == DialogResult.OK)
                {
                    lvValue = ff.SelectedValue;
                }
                else return;
            }
            else if (lvValue.Split(',').Length > 1)
            {
                var ff = new Dialog.fSelectDataList(lvValue.Split(','));
                if (ff.ShowDialog() == DialogResult.OK)
                {
                    lvValue = ff.SelectedValue;
                }
                else return;
            }

            if (TagStr == "RID" || TagStr == "ID")
            {
                tbRID.Text = lvValue;
            }
            else if (TagStr == "SID")
            {
                tbSID.Text = lvValue;

                //If SID value is applied, also check print position
                if (this.PrintPos.isEmpty() || this.PrintPos == "5" && lvValue.isEmpty() == false)
                {
                    try
                    {
                        using (var ta = new DataSet1TableAdapters.K4EE_Component_Reel_Print_InformationTableAdapter())
                        {
                            var dr = ta.GetBySID(PUB.MCCode, lvValue).FirstOrDefault();
                            if (dr != null)  //자료가잇는 경우에만 적용
                            {
                                this.PrintPos = dr.PrintPosition;
                                this.DisplayPrintPos(this.PrintPos);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        UTIL.MsgE("SID:" + lvValue + " failed to load print position value\n" + ex.Message);
                    }
                }
            }
            else if (TagStr == "VLOT")
            {
                tbVLOT.Text = lvValue;
            }
            else if (TagStr == "QTY")
            {
                PUB.log.Add($"Quantity updated {tbQTY.Text}->{lvValue}");
                tbQTY.Text = lvValue;
            }
            else if (TagStr == "MFGDATE")
            {
                tbMFG.Text = lvValue;
            }
            else if (TagStr == "SUPPLY")
            {
                tbVName.Text = lvValue;
            }
            else if (TagStr == "PARTNO")
            {
                tbpartno.Text = lvValue;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            CancleAutoConfirm();
            //Pub.Result.JobEndTime
            //If SID is changed, put original value in sid0
            if (tbSID.Text.isEmpty())
            {
                UTIL.MsgE("SID is missing");
                tbSID.Focus();
                return;
            }
            func_sidconv(false);
        }

        void CancleAutoConfirm()
        {
            if (VAR.BOOL[eVarBool.Option_AutoConf])
            {
                btOK.Text = "◆ Input Complete ◆";
                tmAutoConfirm.Stop();
            }
        }

        void func_sidconv(Boolean auto)
        {
            var sid = tbSID.Text.Trim();


            if (auto)
            {
                //Query from database
                try
                {
                    var dr = PUB.Result.DTSidConvert.Where(t => t.SIDFrom == sid);
                    if (dr.Any() == true)   //Conversion table data exists
                    {
                        if (dr.Count() == 1)
                        {
                            //Create only when original has no value
                            if (lbSID0.Text.isEmpty())
                            {
                                lbSID0.Tag = tbSID.Text;    //Since conversion info exists, put current info into original value
                                lbSID0.Text = tbSID.Text;   //Original value
                            }
                            tbSID.Text = dr.First().SIDTo; //Put converted value into current value
                            var drsid = dr.First();
                            PUB.log.Add(string.Format("SID auto conversion {0}->{1}", drsid.SIDFrom, drsid.SIDTo));
                        }
                        else
                        {
                            PUB.log.AddE(string.Format("SID auto conversion failed {0}, found SID conversion info count:{1}", sid, dr.Count()));
                            PUB.Result.DTSidConvertMultiList.Add(sid);
                        }
                    }
                    else
                    {
                        PUB.Result.DTSidConvertEmptyList.Add(sid);
                        PUB.log.Add(string.Format("SID auto conversion failed - no conversion data sid:{0}", sid));
                    }

                }
                catch (Exception ex)
                {
                    PUB.log.AddE("SID conversion operation failed message:" + ex.Message);
                }
            }
            else
            {
                var f = new Dialog.fNewSID(sid);
                if (f.ShowDialog() != DialogResult.OK) return;

                if (lbSID0.Tag == null || lbSID0.Tag.ToString().isEmpty())  //Is there previously converted info?
                {
                    //원본값 백업
                    lbSID0.Tag = tbSID.Text;
                    lbSID0.Text = tbSID.Text;

                    //from & to
                    PUB.Result.LastSIDFrom = tbSID.Text.Trim();
                    PUB.Result.LastSIDTo = f.NewSID.Trim();

                    PUB.log.Add($"Entering last record due to manual SID selection from={PUB.Result.LastSIDFrom},to={PUB.Result.LastSIDTo}");
                }

                PUB.Result.LastSIDCnt = f.FindSIDCount;
                tbSID.Text = f.NewSID;
            }

            UpdateSID(auto);

        }

        /// <summary>
        /// 데이터베이스의 정보를 UI에 반영한다
        /// </summary>
        /// <param name="auto"></param>
        void UpdateSID(Boolean auto = false)
        {
            //고칠게 없다.
            if (TbCustCode.Text.isEmpty() == false && tbpartno.Text.isEmpty() == false && this.PrintPos.isEmpty() == false)
            {
                return;
            }

            //sid 가 변경되었으나 해당 sid  인쇄위치 및 customer / part no 값을 확인 합니다.
            var taSID = new DataSet1TableAdapters.K4EE_Component_Reel_SID_InformationTableAdapter();
            var taPRN = new DataSet1TableAdapters.K4EE_Component_Reel_Print_InformationTableAdapter();

            try
            {
                var sid = this.tbSID.Text.Trim();

                var dr = taSID.GetBySID(PUB.MCCode, sid).FirstOrDefault();
                var drP = taPRN.GetBySID(PUB.MCCode, sid).FirstOrDefault();

                if (dr == null) return;

                var msg = "SID 변경으로 인해 다음 자료를 입력할까요?";
                Boolean bupdate = false;
                if (dr.CustCode.isEmpty() == false && dr.CustCode != TbCustCode.Text)
                {
                    msg += "\nCustomer Code : " + dr.CustCode;
                    msg += "\nCustomer Name : " + dr.CustName;
                    bupdate = true;
                }

                if (dr.PartNo.isEmpty() == false && dr.PartNo != tbpartno.Text)// tbpartno.Text.isEmpty())
                {
                    msg += "\nPart No : " + dr.PartNo;
                    bupdate = true;
                }

                if (drP.PrintPosition.isEmpty() == false)
                {
                    msg += "\nPrint Position : " + drP.PrintPosition;
                    bupdate = true;
                }
                if (bupdate == false)
                {
                    //Util.MsgE("변경 가능한 자료가 없습니다");
                    return;
                }

                //Display on screen - apply without asking in auto mode
                if (auto == false && UTIL.MsgQ(msg) != DialogResult.Yes) return;
                if (dr.CustCode.isEmpty() == false && TbCustCode.Text != dr.CustCode)
                {
                    TbCustCode.Text = dr.CustCode;
                    tbCustName.Text = dr.CustName;
                }

                if (dr.PartNo.isEmpty() == false && tbpartno.Text != dr.PartNo)
                {
                    this.tbpartno.Text = dr.PartNo;
                }

                if (drP.PrintPosition.isEmpty() == false)
                {
                    this.PrintPos = drP.PrintPosition;
                    DisplayPrintPos(this.PrintPos);
                }

                //이 SID의 최근 MFGDate 와 Qty 를 추가 체크한다  210326
                if (tbMFG.Text.isEmpty() || tbQTY.Text.isEmpty())
                {
                    func_CheckDateQty();
                }
            }
            catch (Exception ex)
            {
                PUB.log.AddE($"SID information update failed: {ex.Message}");
            }
            taSID.Dispose();
            taPRN.Dispose();
        }

        Boolean func_CheckDateQty()
        {
            Boolean bwarn = false;

            var sid = this.tbSID.Text.Trim();
            if (sid.isEmpty()) return false; //sid가 없다.

            //최근 6시간안에서 동일한 데이터를 찾아서 제안 해준다
            var sd = DateTime.Now.AddHours(-1);
            var sql = "select * from K4EE_Component_Reel_Result with (nolock)" +
                " where jtype = @jtype and sid = @sid and isnull(QR,'') <> '' and stime >= @sd" +
                " order by wdate desc";
            var ps = new SqlParameter[] {
                 new SqlParameter("jtype", PUB.Result.JobType2),
                 new SqlParameter("sid", sid),
                 new SqlParameter("sd", sd),
            };

            DataSet1.K4EE_Component_Reel_ResultRow preData = null;
            var preDatas = DBHelper.Get(sql, ps);
            if (preDatas.Rows.Count > 0) preData = preDatas.Rows[0] as DataSet1.K4EE_Component_Reel_ResultRow;

            

            //기존자료가 없다면 취소
            if (preData == null) return false;
            var amkorid = new StdLabelPrint.CAmkorSTDBarcode(preData.QR);

            if (preData.VNAME != tbVName.Text)
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},mfgdata={1}", sid, amkorid.MFGDate));
                tbVName.Text = preData.VNAME;
                bwarn = true;
                //if (func_existbcddata(amkorid.MFGDate) == false)
                {
                    AddErrorMessage("V.Name updated from previous record");
                    PUB.log.Add("'V.Name' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                        "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }
            }


            if (amkorid.MFGDate.isEmpty() == false && tbMFG.Text.isEmpty())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},mfgdata={1}", sid, amkorid.MFGDate));
                tbMFG.Text = amkorid.MFGDate;
                bwarn = true;
                if (func_existbcddata(amkorid.MFGDate) == false)
                {
                    AddErrorMessage("MFG updated from previous record");
                    PUB.log.Add("'MFG Date' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                        "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }
            }

            if (amkorid.QTY > 0 && tbQTY.Text.isEmpty())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                PUB.log.Add($"Quantity updated {tbQTY.Text}->{amkorid.QTY}");
                tbQTY.Text = amkorid.QTY.ToString();
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},qty={1}", sid, amkorid.QTY));
                bwarn = true;
                if (func_existbcddata(amkorid.QTY.ToString()) == false)
                {
                    AddErrorMessage("QTY updated from previous record");
                    PUB.log.Add("'Qty' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                            "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }

            }

            if (amkorid.PARTNO.isEmpty() == false && tbpartno.Text.isEmpty())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                tbpartno.Text = amkorid.PARTNO;
                bwarn = true;
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},PARTNO={1}", sid, amkorid.PARTNO));
                if (func_existbcddata(amkorid.PARTNO) == false)
                {
                    AddErrorMessage("PartNo updated from previous record");
                    PUB.log.Add("'Part No' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                            "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }

            }

            //Customer
            if (amkorid.RID.Length > 10 && amkorid.RID.Substring(2, 4) != TbCustCode.Text.Trim())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                TbCustCode.Text = amkorid.RID.Substring(2, 4);
                bwarn = true;
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},VLOT={1}", sid, amkorid.VLOT));
                if (func_existbcddata(TbCustCode.Text) == false)
                {
                    AddErrorMessage("Customer Code updated from previous record");
                    PUB.log.Add("'Customer Code' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                        "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);


                }
                btCustomAutoInput.PerformClick();
            }


            if (amkorid.VLOT.isEmpty() == false && tbVLOT.Text.isEmpty())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                tbVLOT.Text = amkorid.VLOT;
                bwarn = true;
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},VLOT={1}", sid, amkorid.VLOT));
                if (func_existbcddata(amkorid.VLOT) == false)
                {
                    AddErrorMessage("VLOT updated from previous record");
                    PUB.log.Add("'Vender LOT' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                        "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }

            }

            if (amkorid.VENDERNAME.isEmpty() == false && tbVName.Text.isEmpty())
            {
                //해당 mfgdae 가 바코드목록에 잇다면 바로 적용
                //업다면 적용하고 적용 메세지 표시한다
                tbVName.Text = amkorid.VENDERNAME;
                bwarn = true;
                //Pub.log.Add(string.Format("이전결과에서 값 업데이트 sid:{0},VENDERNAME={1}", sid, amkorid.VENDERNAME));
                if (func_existbcddata(amkorid.VENDERNAME) == false)
                {
                    AddErrorMessage("VNAME updated from previous record");
                    PUB.log.Add("'Vender Name' value entered from previous record\n" +
                        "Previous work time: " + ((DateTime)(preData.wdate)).ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
                        "SID : " + preData.SID + "\n" +
                        "MFG Date : " + amkorid.MFGDate + "\n" +
                        "Part No : " + amkorid.PARTNO + "\n" +
                        "Vender Lot : " + amkorid.VLOT + "\n" +
                        "Vender Name : " + amkorid.VENDERNAME + "\n" +
                        "QTY : " + amkorid.QTY.ToString(), true);
                }

            }

            return bwarn;

        }
        /// <summary>
        /// Check if the data exists in Keyence barcode list
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        Boolean func_existbcddata(string data)
        {
            var lv = lvbcdList.FindItemWithText(data);
            return lv != null;
        }

        private void btReqQty_Click(object sender, EventArgs e)
        {
            var msg = string.Empty;
            var rid = tbRID.Text.Trim();
            if (rid.isEmpty())
            {
                UTIL.MsgE("Reel ID is required");
                return;
            }
            if (AR.SETTING.Data.OnlineMode == false)
            {
                UTIL.MsgE("Cannot be used in offline mode");
                return;
            }

            var cnt = 0;// (Amkor.RestfulService.get_stock_count(rid, out msg));
            if (cnt > 0)
            {
                var oldCnt = int.Parse(tbQTY.Text.Replace(",", ""));
                var newCnt = (int)cnt;
                if (oldCnt == newCnt)
                {
                    //Quantities are same, no processing needed
                }
                else
                {
                    //If numbers are different?
                    if (UTIL.MsgQ(string.Format("Do you want to change the quantity?\nCurrent: {0}\nServer: {1}", tbQTY.Text, newCnt)) == DialogResult.Yes)
                    {
                        PUB.log.Add($"Quantity updated {tbQTY.Text}->{newCnt}");
                        tbQTY.Text = newCnt.ToString();
                    }
                }
            }
            else
            {
                UTIL.MsgE("Server quantity check failed\n\n" + msg);
            }
        }

        private void tbSupply_TextChanged(object sender, EventArgs e)
        {

        }


        private void label13_Click(object sender, EventArgs e)
        {
            //라벨위치
            //라벨위치느느 클릭해서 고칠필요 없다
        }


        private void label22_Click(object sender, EventArgs e)
        {
            //부착위치
            var lb = sender as Label;
            PrintPos = lb.Tag.ToString();
            DisplayPrintPos(PrintPos);
        }

        void DisplayPrintPos(string v)
        {
            var lbs = new Label[] { pb7, pb8, pb9, pb4, pb6, pb1, pb2, pb3 };
            foreach (Label item in lbs)
                if (item.Tag.ToString() == v) item.BackColor = Color.Blue;
                else item.BackColor = Color.FromArgb(64, 64, 64);
        }


        //라벨은 여러 위치에서 발견될 수 있다
        //void DisplayLabelPos(byte[] labelpos)
        //{
        //	var lbs = new Label[] { lbl1, lbl2, lbl3, lbl4, lbl6, lbl7, lbl8, lbl9 };
        //	for (int i = 0; i < labelpos.Length; i++)
        //		lbs[i].BackColor = labelpos[i] > 0 ? Color.Blue : Color.FromArgb(64, 64, 64);
        //}

        bool NewReelId = false;
        private void btNewID_Click(object sender, EventArgs e)
        {
            //var id = TbCustCode.Text; // string.Empty;
            //if (id.Length != 4)
            //{
            //    UTIL.MsgE($"올바른 고객번호를 입력하세요\n" +
            //        $"고객번호는 4자리여야 합니다\n" +
            //        $"값 : {id}\n" +
            //        $"길이 : {id.Length}");
            //    return;
            //}
            //if (tbRID.Text.Length > 4) id = tbRID.Text.Substring(0, 4);

            //already check
            bool MakeNewID = true;
            if (tbRID0.Text.isEmpty() == false && tbRID.Text.isEmpty() == false)
            {
                if (UTIL.MsgQ($"This is a newly generated ReelID. Do you want to generate it again?") != DialogResult.Yes)
                {
                    MakeNewID = false;
                }
            }

            //웹서비스로 생성한다.
            if (MakeNewID)
            {
                var sid = tbSID.Text.Trim();
                if (sid.isEmpty())
                {
                    UTIL.MsgE("No SID");
                    return;
                }

                //WMS generates from DB
                var newid = PUB.MakeNewREELID(sid);
                if (newid.success == false)
                {
                    UTIL.MsgE($"No ReelID Data\n{newid.message}", true);
                    return;
                }

                //remain original reel id
                if (this.tbRID0.Text.isEmpty() && tbRID.Text.isEmpty() == false)
                    this.tbRID0.Text = tbRID.Text.Trim();

                this.tbRID.Text = newid.newid;
                NewReelId = true;
                PUB.log.AddI($"New REELID:{newid.newid}(LoaderInfo)");
            }
        }

        private void tbDate_Click(object sender, EventArgs e)
        {
            selectInput(sender as TextBox);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            var dtstr = this.tbMFG.Text.Trim().Replace("-", "").Replace("/", "");
            if (dtstr.Length == 8)
            {
                dt = new DateTime(
                    int.Parse(dtstr.Substring(0, 4)),
                    int.Parse(dtstr.Substring(4, 2)),
                    int.Parse(dtstr.Substring(6, 2)));
            }

            var f = new Dialog.fSelectDay(dt);
            if (f.ShowDialog() == DialogResult.OK)
            {
                this.tbMFG.Text = f.dt.ToShortDateString();
            }
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //클릭하면 입력창을 띄운다
            UTIL.TouchKeyShow(tbRID, "Input REEL ID");
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbSID, "INPUT SID");
        }

        private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbVLOT, "INPUT VENDER LOT");
        }

        private void linkLabel4_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbQTY, "INPUT QTY");
        }

        private void linkLabel5_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbMFG, "INPUT MFG DATE");
        }

        private void linkLabel6_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbVName, "INPUT SUPPLY NAME");
        }

        private void linkLabel7_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //tbpartno
            UTIL.TouchKeyShow(tbpartno, "INPUT CUSTOMER PART NO.");
        }

        private void btPart_Click(object sender, EventArgs e)
        {
            //파트번호자동입력(sid 를 가지고 테이블에서 찾는다)
            if (tbSID.Text.isEmpty())
            {
                UTIL.MsgE("SID value is required", true);
                return;
            }
            var sid = tbSID.Text.Trim();
            using (var db = new DataSet1TableAdapters.K4EE_Component_Reel_SID_InformationTableAdapter())
            {
                var dr = db.GetBySID(PUB.MCCode, sid).FirstOrDefault();
                if (dr == null)
                {
                    UTIL.MsgE("No information found for this SID");
                    return;
                }

                //파트번호가 잇어야 한다.
                if (dr.PartNo != null || dr.PartNo.isEmpty())
                {
                    UTIL.MsgE("Part No value is not entered for this SID");
                    return;
                }

                var partno = dr.PartNo.Trim();
                if (tbpartno.Text.isEmpty()) tbpartno.Text = partno;
                else
                {
                    var dlg = UTIL.MsgQ(string.Format("Would you like to change the Part NO value?\n" +
                        "Existing : " + tbpartno.Text + "\n" +
                        "New :  " + partno));
                    if (dlg == DialogResult.Yes) tbpartno.Text = dr.PartNo;
                }
            }

        }

        private void btCustAutoInput_Click(object sender, EventArgs e)
        {
            using (var db = new DataSet1TableAdapters.K4EE_Component_Reel_SID_InformationTableAdapter())
            {

                var sid = tbSID.Text.Trim();
                if (sid.isEmpty())
                {
                    UTIL.MsgE("SID value is required", true);
                    return;
                }

                var dr = db.GetBySID(PUB.MCCode, sid).FirstOrDefault();
                if (dr == null || dr.CustCode.isEmpty())
                {
                    UTIL.MsgE("No information found for this SID");
                    return;
                }

                //찾은데이터에서 값을 확인한다.
                //Util.MsgI(string.Format("Customer/Vender 정보가 업데이트 되었습니다\n" +
                //		"Customer : {0}\n" +
                //		"Customer Name : {1}\n" +
                //		"Vender Name : {2}", dr.CustCode, dr.CustName, dr.VenderName));

                //벤더네임은 vlot값을 가지고 한다. 210504
                var vlot = this.tbVLOT.Text.Trim();
                if (vlot.isEmpty() == false)
                {
                    using (var taResult = new DataSet1TableAdapters.K4EE_Component_Reel_ResultTableAdapter())
                    {
                        var dr2 = taResult.GetByLastVLotOne(AR.SETTING.Data.McName, vlot).FirstOrDefault();
                        if (dr2 != null)
                        {
                            tbVName.Text = dr2.VNAME;
                        }
                    }
                }
                TbCustCode.Text = dr.CustCode;
                tbCustName.Text = dr.CustName;

            }


        }

        private void linkLabel8_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(TbCustCode, "INPUT SUPPLY CODE");
        }

        private void button7_Click(object sender, EventArgs e)
        {
            //진수석님 데이터에서 찾아본다.
            var custcode = TbCustCode.Text.Trim();
            var partno = tbpartno.Text.Trim();
            if (partno.isEmpty())
            {
                UTIL.MsgE("The following information is required to find SID\n" +
                    "1. Part No");
                return;
            }

            //각 상황에 따라 다르다.
            using (var db = new DataSet1TableAdapters.K4EE_Component_Reel_SID_InformationTableAdapter())
            {
                var amksid = string.Empty;
                var dtSIDInfo = db.GetData(PUB.MCCode);

                if (custcode.isEmpty() == false && partno.isEmpty() == false)
                {
                    var dr = dtSIDInfo.Where(t => t.CustCode == custcode && t.PartNo == partno && string.IsNullOrEmpty(t.SID) == false).FirstOrDefault();
                    if (dr != null && dr.SID.isEmpty() == false)
                    {
                        amksid = dr.SID;
                    }
                    else
                    {
                        UTIL.MsgE("Cannot confirm SID corresponding to registered Customer Code/Part No\n" +
                            "Customer Code : " + custcode + "\n" +
                            "Part No : " + partno);
                        return;
                    }
                }
                else if (custcode.isEmpty() == false)
                {
                    var drow = dtSIDInfo.Where(t => t.CustCode == custcode && string.IsNullOrEmpty(t.SID) == false).ToList();
                    if (drow == null || drow.Count < 1)
                    {
                        UTIL.MsgE("Cannot find SID for the registered Customer Code\nCustomer: " + custcode);
                        return;
                    }
                    var f = new fSelectDataList(drow.Select(t => t.SID).ToArray());
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        amksid = f.SelectedValue;
                    }
                    else
                    {
                        UTIL.MsgE("User selection was canceled");
                        return;
                    }
                }
                else if (partno.isEmpty() == false)
                {
                    var drow = dtSIDInfo.Where(t => t.PartNo == partno && string.IsNullOrEmpty(t.SID) == false).ToList();
                    if (drow == null || drow.Count < 1)
                    {
                        UTIL.MsgE("Cannot find SID for the registered Part No\n" + "Part No: " + partno);
                        return;
                    }

                    var sidarr = drow.Select(t => t.SID).ToList();
                    var lst = new List<String>();
                    foreach (var item in sidarr)
                    {
                        var m101 = string.Empty;
                        var m103 = item.Trim();
                        var m106 = string.Empty;
                        lst.Add(m101 + ";" + m103 + ";" + m106);
                    }
                    var f = new Dialog.fSelectSID(lst);
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        var returndata = f.Value.Split(';');
                        amksid = returndata[1].Trim();
                    }
                    else
                    {
                        UTIL.MsgE("User selection was canceled");
                        return;
                    }
                }

                if (amksid.isEmpty() == false)
                {
                    PUB.log.Add(string.Format("Amkor SID search code={0},part={1},sid={2}", custcode, partno, amksid));
                    tbSID.Text = amksid;
                    UpdateSID();
                }
                else
                {
                    PUB.log.Add(string.Format("SID search failed - no SID found\n" +
                        "Cust:{0}\n" +
                        "PartNo:{1}", custcode, partno));
                }
            }




        }

        private void btIDCheck_Click(object sender, EventArgs e)
        {
            //중복검사
            var rid = tbRID.Text.Trim();
            if (rid.isEmpty())
            {
                UTIL.MsgE("Reel ID value is missing");
                return;
            }
            if (AR.SETTING.Data.OnlineMode == false)
            {
                UTIL.MsgE("Cannot be used in offline mode");
                return;
            }

            UTIL.MsgE("WMS function not available");
            //var result = Amkor.RestfulService.get_existed_matl_by_id(rid);
            //if (result.Complete == false)
            //{
            //    UTIL.MsgE(result.Message);
            //}
            //else
            //{
            //    if (result.Result == true)
            //    {
            //        UTIL.MsgE($"This ID is a duplicate ID\nValue: {rid}");
            //        return;
            //    }
            //    else
            //    {
            //        UTIL.MsgI($"해당 ID는 중복되지 않았습니다\n{rid}");
            //    }
            //}
        }

        private void button9_Click(object sender, EventArgs e)
        {
            var f = new Dialog.fSelectCustInfo();
            if (f.ShowDialog() == DialogResult.OK)
            {
                this.tbCustName.Text = f.CustName;
                this.TbCustCode.Text = f.CustCode;
                PUB.log.Add(string.Format("User directly selected Customer {0}:{1}", tbCustName.Text, TbCustCode.Text));
            }
        }

        Boolean CheckRID()
        {
            var rid = tbRID.Text.Trim();
            if (rid.Length < 10) return false;
            //var cut = TbCustCode.Text.Trim();
            //if (rid.Substring(2, 4) != cut)
            //{
            //    return false;
            //}
            return true;
        }
        Boolean autoconf = false;
        Boolean warn = false;
        Boolean samesidwarn = false;
        private void btOK_Click(object sender, EventArgs e)
        {
            bool topmost = this.TopMost;
            //var IsBypas = VAR.STR[eVarString.JOB_TYPE] == "BP";
            if (System.Diagnostics.Debugger.IsAttached)
                this.TopMost = false;

            var itemC = PUB.Result.ItemDataC;

            //manu 목록에 없다면 추가 해준다.
            var manuName = tbVName.Text.Trim().ToLower();
            if (manuName.isEmpty() == false)
            {
                lock (PUB.Result.dsList)
                {
                    if (PUB.Result.dsList.Supply.Where(t => t.TITLE.ToLower() == manuName).Any() == false)
                    {
                        //기존 manu 목록에 없으니 추가한다.
                        var newdr = PUB.Result.dsList.Supply.NewSupplyRow();
                        newdr.TITLE = tbVName.Text.Trim();
                        PUB.Result.dsList.Supply.AddSupplyRow(newdr);
                        PUB.Result.SaveListDB();
                    }
                }
            }

            //회전용데이터가 여러개 있다면 처리하지 않는다.
            #region "Rotate Data"
            if (this.lvbcdList.CheckedItems.Count != 1)
            {
                PUB.AddSystemLog(Application.ProductVersion, "MAIN", $"회전 기준데이터가 {this.lvbcdList.CheckedItems.Count}건 입니다");
                UTIL.MsgE("Only one rotation reference data should be selected");
                return;
            }
            if (this.lvbcdList.CheckedItems.Count == 1)
            {
                var bcddata = lvbcdList.CheckedItems[0].SubItems[1].Text;
                lock (itemC.VisionData.barcodelist)
                {
                    foreach (var item in itemC.VisionData.barcodelist)
                    {
                        if (item.Value.Data == bcddata)
                        {
                            PUB.log.Add(string.Format("Rotation reference barcode value {0}", item.Value.Data));
                            item.Value.UserActive = true;
                        }
                        else item.Value.UserActive = false;
                    }
                }
            }
            #endregion

            //마지막에 작업한 데이터와 비교 ?? 220104
            //if (tbSID.Text == PUB.Result.LastSIDTo && tbVName.Text != PUB.Result.LastVName)
            //{
            //	PUB.Result.LastVName = tbVName.Text;
            //	PUB.log.Add($"Vname 값을 저장하여 연속작업시 사용합니다 sid:{tbSID.Text},vname:{tbVName.Text}");
            //}

            //필수값 입력 확인
            #region "Check iNput Data"
            if (tbSID.Text.isEmpty())
            {
                UTIL.MsgE("SID is not entered");
                tbSID.Focus();
                return;
            }
            if (tbVLOT.Text.isEmpty())
            {
                UTIL.MsgE("VLOT is not entered");
                tbVLOT.Focus();
                return;
            }
            if (tbQTY.Text.isEmpty())
            {
                UTIL.MsgE("QTY is not entered");
                tbQTY.Focus();
                return;
            }
            if (tbMFG.Text.isEmpty())
            {
                UTIL.MsgE("MFG-DATE is not entered");
                tbMFG.Focus();
                return;
            }
            if (tbRID.Text.isEmpty())
            {
                UTIL.MsgE("REEL ID is not entered");
                tbRID.Focus();
                return;
            }
            if (PUB.Result.vModel.IgnorePartNo == false && this.tbpartno.Text.isEmpty())
            {
                UTIL.MsgE("PART No is not entered");
                tbpartno.Focus();
                return;
            }
            if (PUB.OPT_BYPASS() == false && PUB.Result.vModel.DisablePrinter == false && this.PrintPos.isEmpty())
            {
                UTIL.MsgE("Print attachment position is not specified");
                return;
            }
            if (PUB.OPT_BYPASS() == false && this.tbVName.Text.isEmpty())
            {
                UTIL.MsgE("Vendor Name is not entered");
                return;
            }
            #endregion

            //현재 작업모드와 SID가 일치하는지 확인한다.
            var sidNew = this.tbSID.Text.Trim();
            var sidOld = this.lbSID0.Text.Trim();//.Tag == null ? string.Empty : lbSID0.Text;v
            var partNo = this.tbpartno.Text.Trim();
            var custCode = this.TbCustCode.Text.Trim();

            if (VAR.BOOL[eVarBool.Opt_NewReelID] && (tbRID.Text.isEmpty() || NewReelId == false))
            {
                UTIL.MsgE("New Reel ID generation mode.\nPlease generate REEL ID.");
                this.TopMost = topmost;
                return;
            }

            //sid전환모드 확인 230510
            if (VAR.BOOL[eVarBool.Opt_SIDConvert])
            {
                if (lbSID0.Tag == null || lbSID0.Text.Length != 9)
                {
                    UTIL.MsgE("SID conversion mode. Please perform SID conversion");
                    this.TopMost = topmost;
                    return;
                }
            }


            //신규릴 모드일때에만 CustomerCode 값을 체크한다
            if (VAR.BOOL[eVarBool.Opt_NewReelID] && CheckRID() == false)
            {
                PUB.AddSystemLog(Application.ProductVersion, "MAIN", $"Reel ID 의 Customer Code 값이 현재 값과 일치하지 않습니다(RID:{tbRID.Text}/CUST:{TbCustCode.Text})");
                UTIL.MsgE("Reel ID Customer Code value does not match the current value\nRegenerate REEL ID if necessary");
                this.TopMost = topmost;
                return;
            }

            //자동 실행이나 LOT값이 변경되면 자동 실행을 취소한다
            var lot = this.tbVLOT.Text.Trim();
            if (warn == false && autoconf == true)
            {
                if (AR.SETTING.Data.OnlineMode)
                {
                    var taQ = new DataSet1TableAdapters.QueriesTableAdapter();
                    var LastLot = taQ.GetLastVLotFromSID(sidNew);
                    if (LastLot.isEmpty() == false && LastLot.Equals(lot) == false)
                    {
                        UTIL.MsgE("Previous LOT value does not match. Auto confirmation is canceled\n" +
                            $"Previous LOT:{LastLot}, New LOT:{lot}");
                        warn = true;
                        this.TopMost = topmost;
                        return;
                    }
                }
            }



            //모든자료는 존재한다 저장가능하다
            if (AR.SETTING.Data.OnlineMode)
            {
                //시드정보테이블의 데이터를 역으로 저장한 경우
                if (VAR.BOOL[eVarBool.Opt_ApplySIDInfo] && VAR.BOOL[eVarBool.Opt_SID_WriteServer])
                {
                    Dictionary<string, string> wheres = new Dictionary<string, string>();
                    Dictionary<string, string> columns = new Dictionary<string, string>();

                    //조건절생성
                    if (VAR.BOOL[eVarBool.Opt_SID_Where_CustCode]) wheres.Add("CustCode", TbCustCode.Text);
                    if (VAR.BOOL[eVarBool.Opt_SID_Where_PartNo]) wheres.Add("PartNo", tbpartno.Text);
                    if (VAR.BOOL[eVarBool.Opt_SID_Where_SID]) wheres.Add("SID", tbSID.Text);
                    if (VAR.BOOL[eVarBool.Opt_SID_Where_VLOT]) wheres.Add("VenderLot", tbVLOT.Text);

                    //Make Target COlumns
                    if (VAR.BOOL[eVarBool.Opt_SID_Apply_CustCode]) columns.Add("CustCode", TbCustCode.Text);
                    if (VAR.BOOL[eVarBool.Opt_SID_Apply_PartNo]) columns.Add("PartNo", tbpartno.Text);
                    if (VAR.BOOL[eVarBool.Opt_SID_Apply_PrintPos]) columns.Add("PrintPosition", this.PrintPos);
                    if (VAR.BOOL[eVarBool.Opt_SID_Apply_SID])
                    {
                        //SID변환기능이 동작한상태에서는 변환된 SID정보를 저장하지 않는다 230510
                        if (VAR.BOOL[eVarBool.Opt_SIDConvert])
                        {
                            PUB.log.AddAT($"SID information will not be updated due to SID conversion feature usage");
                        }
                        else columns.Add("SID", tbSID.Text);
                    }
                    if (VAR.BOOL[eVarBool.Opt_SID_Apply_VenderName]) columns.Add("VenderName", tbVName.Text);
                    ServerWriteINF(columns, wheres);
                }


                //시드변환정보 저장
                if (VAR.BOOL[eVarBool.Opt_SIDConvert] && VAR.BOOL[eVarBool.Opt_SID_WriteServer])
                {
                    var SIDO = lbSID0.Text.Trim();
                    var SIDN = tbSID.Text.Trim();
                    if (SIDO.Equals(SIDN) == false && SIDO.isEmpty() == false && SIDN.isEmpty() == false && SIDO.Length == 9 && SIDO.Length == SIDN.Length)
                    {
                        Dictionary<string, string> wheres = new Dictionary<string, string>();
                        Dictionary<string, string> columns = new Dictionary<string, string>();

                        //조건절생성
                        wheres.Add("SIDFrom", SIDO);

                        //Make Target COlumns
                        columns.Add("SIDTo", SIDN);
                        columns.Add("SIDFrom", SIDO);   //250106
                        ServerWriteCNV(columns, wheres);
                    }
                }
                else PUB.log.AddI($"Seed conversion information(SID) will not be saved");

                //시드변환테이블에 데이터를 저장하는 경우이다.
                if (VAR.BOOL[eVarBool.Opt_ApplySIDConv] && VAR.BOOL[eVarBool.Opt_Conv_WriteServer])
                {
                    Dictionary<string, string> wheres = new Dictionary<string, string>();
                    Dictionary<string, string> columns = new Dictionary<string, string>();

                    //조건절생성
                    if (VAR.BOOL[eVarBool.Opt_Conv_Where_CustCode]) wheres.Add("CustCode", TbCustCode.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Where_PartNo]) wheres.Add("PartNo", tbpartno.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Where_SID]) wheres.Add("SIDTo", tbSID.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Where_VLOT]) wheres.Add("VenderLot", tbVLOT.Text);

                    //Make Target COlumns
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_CustCode]) columns.Add("CustCode", TbCustCode.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_PartNo]) columns.Add("PartNo", tbpartno.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_PrintPos]) columns.Add("PrintPosition", this.PrintPos);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_VenderName]) columns.Add("VenderName", tbVName.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_Batch]) columns.Add("batch", tbBatch.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_QtyMax]) columns.Add("qtymax", tbQtyMax.Text);
                    if (VAR.BOOL[eVarBool.Opt_Conv_Apply_SID]) columns.Add("SIDFrom", lbSID0.Text.Trim());  //250106

                    PUB.log.Add($"SID conversion info save columns:{string.Join(",", columns)},where:{string.Join("',", wheres)}");
                    ServerWriteCONVINF(columns, wheres);
                }
                else PUB.log.AddI($"Seed conversion information(detailed) will not be saved");
            }

            //값을 설정해주고 빠져나간다
            itemC.VisionData.SetRID(tbRID.Text.Trim(), "USER CONFIRM");//.RID = tbRID.Text.Trim();
            itemC.VisionData.RID0 = tbRID0.Text.Trim();// tbRID.Text.Trim();// tbRID.Tag.ToString(); //210429
            itemC.VisionData.RIDNew = this.NewReelId;


            itemC.VisionData.SID0 = lbSID0.Text.Trim();    //orginal sid value

            if (lbSID0.Text.isEmpty() &&
                itemC.VisionData.SID.isEmpty() == false &&
                itemC.VisionData.SID.Equals(tbSID.Text.Trim()) == false)
                itemC.VisionData.SID0 = itemC.VisionData.SID;


            itemC.VisionData.SID = tbSID.Text.Trim();      //sid convert value
            itemC.VisionData.QTYMAX = tbQtyMax.Text.Trim();
            itemC.VisionData.BATCH = tbBatch.Text.Trim();

            itemC.VisionData.VLOT = tbVLOT.Text.Trim();
            itemC.VisionData.QTY = tbQTY.Text.Trim();
            itemC.VisionData.MFGDATE = tbMFG.Text.Trim();
            itemC.VisionData.VNAME = tbVName.Text.Trim();
            itemC.VisionData.PARTNO = tbpartno.Text.Trim();

            //Apply Confirm Data
            if (this.autoconf) itemC.VisionData.ConfirmAuto = true;
            itemC.VisionData.ConfirmUser = true;

            //Apply Print Position Data
            itemC.VisionData.PrintPositionData = this.PrintPos;
            itemC.VisionData.PrintPositionCheck = true; //사용자가 확인했다.

            //delete -- 220706
            //this.DisplayLabelPos(itemC.VisionData.LabelPositionData);

            this.PrintPos = itemC.VisionData.PrintPositionData;
            this.DisplayPrintPos(itemC.VisionData.PrintPositionData);

            this.TopMost = topmost;
            this.Close();
        }


        /// <summary>
        /// 지정한 자료를 서버에 기록합니다. 조건절과 대상 열을 제공해야합니다
        /// </summary>
        void ServerWriteINF(Dictionary<string, string> columns, Dictionary<string, string> wheres)
        {
            //변경된 값만 저장여부를 확인할 것이므로 기존 값을 모두 가져온다
            var SQL = "select  top 1 " + string.Join(",", columns.Select(t => "isnull([" + t.Key + "],'') as " + t.Key + "")) +
                " from K4EE_Component_Reel_SID_Information WITH(NOLOCK)";

            var WSQL = $" where MC='{PUB.MCCode}'";
            for (int i = 0; i < wheres.Count; i++)
            {
                var col = wheres.ElementAt(i);
                var colname = col.Key;
                var colvalue = col.Value;
                WSQL += " AND ";
                WSQL += $" {colname}='{colvalue.Replace("'", "''")}'";
            }
            SQL += WSQL;

            Dictionary<String, string> UpdateTarget = new Dictionary<string, string>();
            var CN = new System.Data.SqlClient.SqlConnection();
            CN.ConnectionString = Properties.Settings.Default.CS;
            var CMD = new System.Data.SqlClient.SqlCommand(SQL, CN);
            CN.Open();
            var DAR = CMD.ExecuteReader();
            var NoData = true;
            Dictionary<String, string> InsertTarget = new Dictionary<string, string>();
            while (DAR.Read())
            {
                NoData = false;
                foreach (var col in columns)
                {
                    var vStr = DAR[col.Key].ToString();
                    var cStr = col.Value;
                    if (vStr.Equals(cStr) == false)
                    {
                        //differenct value
                        UpdateTarget.Add(col.Key, cStr);
                    }
                }
            }
            DAR.Close();
            //자료가 없다면 데이터를 추가한다.
            if (NoData)
            {
                foreach (var col in columns)
                {
                    InsertTarget.Add(col.Key, col.Value);
                }
                foreach (var item in wheres)
                {
                    if (InsertTarget.ContainsKey(item.Key) == false)
                        InsertTarget.Add(item.Key, item.Value);
                }
            }

            if (UpdateTarget.Count > 0) //if update target 
            {

                var dlgMsg = $"다음 값을 서버(SID정보)에 저장 하시겠습니까?\n";
                foreach (var item in UpdateTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";

                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {

                    //check double data 220706
                    var CSQL = "select count(*) from K4EE_Component_Reel_SID_Information WITH(NOLOCK) ";
                    CSQL += WSQL;
                    CMD.CommandText = CSQL;
                    var cnt = int.Parse(CMD.ExecuteScalar().ToString());
                    var whke = string.Join(",", wheres.Select(t => t.Key).ToList());
                    if (cnt < 1)
                    {
                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"Cannot update information because target reel information is missing\n" + whke);
                    }
                    else if (cnt > 1)
                    {

                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"Cannot update information because multiple target reel information exists ({cnt} items)\n" + whke);
                    }
                    else
                    {
                        var USQL = $"update K4EE_Component_Reel_SID_Information set [MC]='{PUB.MCCode}'," +
                        string.Join(",", UpdateTarget.Select(t => "[" + t.Key + "]='" + t.Value + "'"));

                        USQL += WSQL;
                        try
                        {
                            CMD.CommandText = USQL;
                            var UpdateOK = CMD.ExecuteNonQuery() == 1;
                            if (UpdateOK == false)
                            {
                                UTIL.MsgE("Save Error");
                            }
                        }
                        catch (Exception ex)
                        {
                            UTIL.MsgE("Save Error\n" + ex.Message);
                        }
                    }
                }
            }
            if (InsertTarget.Count > 0)
            {

                var dlgMsg = $"다음 값을 서버에 저장 하시겠습니까?\n";
                foreach (var item in InsertTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";

                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {
                    var ISQL = $"insert into K4EE_Component_Reel_SID_Information ([MC],wdate," +
                        string.Join(",", InsertTarget.Select(t => "[" + t.Key + "]")) + ") values(" +
                        $"'{PUB.MCCode}',getdate()," +
                        string.Join(",", InsertTarget.Select(t => "'" + t.Value.Replace("'", "''") + "'")) + ")";

                    //ISQL += WSQL;
                    try
                    {
                        CMD.CommandText = ISQL;
                        var UpdateOK = CMD.ExecuteNonQuery() == 1;
                        if (UpdateOK == false)
                        {
                            UTIL.MsgE("Save Error");
                        }
                    }
                    catch (Exception ex)
                    {
                        UTIL.MsgE("Save Error\n" + ex.Message);
                    }
                }

            }
            CN.Close();
            CN.Dispose();
        }
        /// <summary>
        /// 지정한 자료를 서버에 기록합니다. 조건절과 대상 열을 제공해야합니다
        /// </summary>
        void ServerWriteCNV(Dictionary<string, string> columns, Dictionary<string, string> wheres)
        {
            //변경된 값만 저장여부를 확인할 것이므로 기존 값을 모두 가져온다
            var tableName = "K4EE_Component_Reel_SID_Convert";
            var SQL = "select  top 1 " + string.Join(",", columns.Select(t => "isnull([" + t.Key + "],'') as " + t.Key + "")) +
                $" from {tableName} WITH(NOLOCK) ";

            var WSQL = $" where isnull(MC,'{PUB.MCCode}')='{PUB.MCCode}'";
            for (int i = 0; i < wheres.Count; i++)
            {
                var col = wheres.ElementAt(i);
                var colname = col.Key;
                var colvalue = col.Value;
                WSQL += " AND ";
                WSQL += $" {colname}='{colvalue.Replace("'", "''")}'";
            }
            SQL += WSQL;

            Dictionary<String, string> UpdateTarget = new Dictionary<string, string>();
            var CN = new System.Data.SqlClient.SqlConnection();
            CN.ConnectionString = Properties.Settings.Default.CS;
            var CMD = new System.Data.SqlClient.SqlCommand(SQL, CN);
            CN.Open();
            var DAR = CMD.ExecuteReader();
            var NoData = true;
            Dictionary<String, string> InsertTarget = new Dictionary<string, string>();
            while (DAR.Read())
            {
                NoData = false;
                foreach (var col in columns)
                {
                    var vStr = DAR[col.Key].ToString();
                    var cStr = col.Value;
                    if (vStr.Equals(cStr) == false)
                    {
                        //differenct value
                        UpdateTarget.Add(col.Key, cStr);
                    }
                }
            }
            DAR.Close();

            //자료가 없다면 데이터를 추가한다.
            if (NoData)
            {
                foreach (var col in columns)
                {
                    InsertTarget.Add(col.Key, col.Value);
                }
                foreach (var item in wheres)
                {
                    if (InsertTarget.ContainsKey(item.Key) == false)
                        InsertTarget.Add(item.Key, item.Value);
                }
            }

            if (UpdateTarget.Count > 0) //if update target 
            {

                var dlgMsg = $"다음 SID변환값을 서버에 업데이트 하시겠습니까?\n";
                foreach (var item in UpdateTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";

                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {

                    //check double data 220706
                    var CSQL = $"select count(*) from {tableName}";
                    CSQL += WSQL;
                    CMD.CommandText = CSQL;
                    var cnt = int.Parse(CMD.ExecuteScalar().ToString());
                    var whke = string.Join(",", wheres.Select(t => t.Key).ToList());
                    if (cnt < 1)
                    {
                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"Cannot update conversion information because target reel information is missing\n" + whke);
                    }
                    else if (cnt > 1)
                    {

                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"Cannot update information because multiple target reel conversion information exists ({cnt} items)\n" + whke);
                    }
                    else
                    {
                        var USQL = $"update {tableName} set isnull([MC],'{PUB.MCCode}')='{PUB.MCCode}'," +
                        string.Join(",", UpdateTarget.Select(t => "[" + t.Key + "]='" + t.Value + "'"));

                        USQL += WSQL;
                        try
                        {
                            CMD.CommandText = USQL;
                            var UpdateOK = CMD.ExecuteNonQuery() == 1;
                            if (UpdateOK == false)
                            {
                                UTIL.MsgE("(CNV)Save Error");
                            }
                        }
                        catch (Exception ex)
                        {
                            UTIL.MsgE("(CNV)Save Error\n" + ex.Message);
                        }
                    }
                }
            }
            if (InsertTarget.Count > 0)
            {

                var dlgMsg = $"다음 변환값을 서버에 추가 하시겠습니까?\n";
                foreach (var item in InsertTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";


                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {
                    var ISQL = $"insert into {tableName} ([MC]," +
                        string.Join(",", InsertTarget.Select(t => "[" + t.Key + "]")) + ") values(" +
                        $"'{PUB.MCCode}'," +
                        string.Join(",", InsertTarget.Select(t => "'" + t.Value.Replace("'", "''") + "'")) + ")";

                    //ISQL += WSQL;
                    try
                    {
                        CMD.CommandText = ISQL;
                        var UpdateOK = CMD.ExecuteNonQuery() == 1;
                        if (UpdateOK == false)
                        {
                            UTIL.MsgE("Save(CNV) Error");
                        }
                    }
                    catch (Exception ex)
                    {
                        UTIL.MsgE("Save(CNV) Error\n" + ex.Message);
                    }
                }

            }
            CN.Close();
            CN.Dispose();

            if (UpdateTarget.Any() || InsertTarget.Any())
            {
                PUB.GetSIDConverDB();
            }
        }


        void ServerWriteCONVINF(Dictionary<string, string> columns, Dictionary<string, string> wheres)
        {
            //변경된 값만 저장여부를 확인할 것이므로 기존 값을 모두 가져온다
            var SQL = "select  top 1 " + string.Join(",", columns.Select(t => "isnull([" + t.Key + "],'') as " + t.Key + "")) +
                " from K4EE_Component_Reel_SID_Convert WITH(NOLOCK) ";

            var WSQL = $" where (MC is null or MC='{PUB.MCCode}')";
            for (int i = 0; i < wheres.Count; i++)
            {
                var col = wheres.ElementAt(i);
                var colname = col.Key;
                var colvalue = col.Value;
                WSQL += " AND ";
                WSQL += $" {colname}='{colvalue.Replace("'", "''")}'";
            }
            SQL += WSQL;

            PUB.log.Add($"ServerWriteCONVINF SQL={SQL}");

            Dictionary<String, string> UpdateTarget = new Dictionary<string, string>();
            var CN = new System.Data.SqlClient.SqlConnection();
            CN.ConnectionString = Properties.Settings.Default.CS;
            var CMD = new System.Data.SqlClient.SqlCommand(SQL, CN);
            CN.Open();
            var DAR = CMD.ExecuteReader();
            var NoData = true;
            Dictionary<String, string> InsertTarget = new Dictionary<string, string>();
            while (DAR.Read())
            {
                NoData = false;
                foreach (var col in columns)
                {
                    var vStr = DAR[col.Key].ToString();
                    var cStr = col.Value;
                    if (vStr.Equals(cStr) == false)
                    {
                        //differenct value
                        UpdateTarget.Add(col.Key, cStr);
                    }
                }
            }
            DAR.Close();
            //자료가 없다면 데이터를 추가한다.
            if (NoData)
            {
                foreach (var col in columns)
                {
                    InsertTarget.Add(col.Key, col.Value);
                }
                foreach (var item in wheres)
                {
                    if (InsertTarget.ContainsKey(item.Key) == false)
                        InsertTarget.Add(item.Key, item.Value);
                }
            }

            if (UpdateTarget.Count > 0) //if update target 
            {

                var dlgMsg = $"다음 값을 서버(변환정보)에 저장 하시겠습니까?\n";
                foreach (var item in UpdateTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";

                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {

                    //check double data 220706
                    var CSQL = "select count(*) from K4EE_Component_Reel_SID_Convert WITH(NOLOCK) ";
                    CSQL += WSQL;
                    CMD.CommandText = CSQL;
                    var cnt = int.Parse(CMD.ExecuteScalar().ToString());
                    var whke = string.Join(",", wheres.Select(t => t.Key).ToList());
                    if (cnt < 1)
                    {
                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"(CONVINFO) 대상 릴 정보가 없어 정보를 업데이트 할 수 없습니다\n" + whke);
                    }
                    else if (cnt > 1)
                    {

                        PUB.log.AddAT("SQL=" + CSQL);
                        UTIL.MsgE($"(CONVINFO) 대상 릴 정보가 복수로({cnt}건) 존재하여 정보를 업데이트 할 수 없습니다\n" + whke);
                    }
                    else
                    {
                        var USQL = $"update K4EE_Component_Reel_SID_Convert set " +
                        string.Join(",", UpdateTarget.Select(t => "[" + t.Key + "]='" + t.Value + "'"));

                        USQL += WSQL;
                        try
                        {
                            CMD.CommandText = USQL;
                            var UpdateOK = CMD.ExecuteNonQuery() == 1;
                            if (UpdateOK == false)
                            {
                                UTIL.MsgE("(CONVINFO) Save Error");
                            }
                        }
                        catch (Exception ex)
                        {
                            UTIL.MsgE("(CONVINFO) Save Error\n" + ex.Message);
                        }
                    }
                }
            }
            if (InsertTarget.Count > 0)
            {

                var dlgMsg = $"다음 값을 서버(변환정보)에 저장 하시겠습니까?\n";
                foreach (var item in InsertTarget)
                    dlgMsg += $"항목:{item.Key} => {item.Value}\n";


                var dlg = UTIL.MsgQ(dlgMsg);
                if (dlg == DialogResult.Yes)
                {
                    var ISQL = $"insert into K4EE_Component_Reel_SID_Convert ([MC],wdate," +
                        string.Join(",", InsertTarget.Select(t => "[" + t.Key + "]")) + ") values(" +
                        $"null,getdate()," +
                        string.Join(",", InsertTarget.Select(t => "'" + t.Value.Replace("'", "''") + "'")) + ")";

                    //ISQL += WSQL;
                    try
                    {
                        CMD.CommandText = ISQL;
                        var UpdateOK = CMD.ExecuteNonQuery() == 1;
                        if (UpdateOK == false)
                        {
                            UTIL.MsgE("(CONVINFO) Save Error");
                        }
                    }
                    catch (Exception ex)
                    {
                        UTIL.MsgE("(CONVINFO) Save Error\n" + ex.Message);
                    }
                }

            }
            CN.Close();
            CN.Dispose();
        }

        private void label26_Click(object sender, EventArgs e)
        {
            var sid = this.tbSID.Text.Trim();
            if (sid.isEmpty()) return;

            var dlg = UTIL.MsgQ("Do you want to search for print position from SID?");
            if (dlg != DialogResult.Yes) return;

            using (var db = new DataSet1TableAdapters.K4EE_Component_Reel_Print_InformationTableAdapter())
            {
                var dr = db.GetBySID(PUB.MCCode, sid).FirstOrDefault();
                if (dr == null || dr.PrintPosition.isEmpty())
                {
                    UTIL.MsgE("No print position stored for entered SID\n" +
                        "SID:" + sid);
                    return;
                }
                this.PrintPos = dr.PrintPosition;
                DisplayPrintPos(this.PrintPos);
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            //데이터베이스 결과에서 자료를 추가한다.
            var result = new DataSet1.K4EE_Component_Reel_ResultDataTable();

            var tabName = "K4EE_Component_Reel_Result with (nolock)";

            //1.sid sid를 먼저 검색한다. 이것이 확률이 제일 높음
            if (this.tbSID.Text.isEmpty() == false)
            {
                var sql = $"select top 5 * from {tabName} where sid = @sid order by wdate desc";
                var list = DBHelper.Get(sql, new SqlParameter("sid", $"{tbSID.Text}"));
                //sql = sql.Replace("@sid", tbSID.Text.Trim());
                if (list.Rows.Count > 0) result.Merge(list);
            }
            //2.파트번호
            if (result.Count == 0 && this.tbpartno.Text.isEmpty() == false)
            {
                var sql = $"select top 5 * from {tabName} where QR like @search order by wdate desc";
                var list = DBHelper.Get(sql, new SqlParameter("search", $"%;{tbpartno.Text}%"));
                if (list.Rows.Count > 0) result.Merge(list);
            }
            //3.벤더LOT
            if (result.Count == 0 && this.tbVLOT.Text.isEmpty() == false)
            {
                var sql = $"select top 5 * from {tabName} where QR like @search order by wdate desc";
                var list = DBHelper.Get(sql, new SqlParameter("search", $"%;{tbVLOT.Text}%"));
                if (list.Rows.Count > 0) result.Merge(list);
            }

            //4.벤더이름
            if (result.Count == 0 && this.tbVName.Text.isEmpty() == false)
            {
                var sql = $"select top 5 * from {tabName} where QR like @search order by wdate desc";
                var list = DBHelper.Get(sql, new SqlParameter("search", $"%;{tbVName.Text}%"));
                if (list.Rows.Count > 0) result.Merge(list);
            }

            //customer code
            if (result.Count < 1)
            {
                UTIL.MsgE("No search results found\nSearch items\n" +
                    "1.SID\n" +
                    "2.LOT\n" +
                    "3.PARTNO\n");
                return;
            }
            var f = new fSelectResult(result);
            if (f.ShowDialog() != DialogResult.OK) return;

            //값이 없는 것만 처리한다.
            string msg = string.Empty;
            var qr = f.SelectedValue.QR;
            var amk = new StdLabelPrint.CAmkorSTDBarcode(qr);
            if (this.tbSID.Text.isEmpty() && amk.SID.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("SID:{0}=>{1}", tbSID.Text, amk.SID);
                tbSID.Text = amk.SID;
            }
            if (this.tbpartno.Text.isEmpty() && amk.PARTNO.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("Part No:{0}=>{1}", tbpartno.Text, amk.PARTNO);
                tbpartno.Text = amk.PARTNO;
            }
            if (this.tbVLOT.Text.isEmpty() && amk.VLOT.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("Vender LOT:{0}=>{1}", tbVLOT.Text, amk.VLOT);
                tbVLOT.Text = amk.VLOT;
            }
            if (this.tbVName.Text.isEmpty() && f.SelectedValue.VNAME.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("Vender Name:{0}=>{1}", tbVName.Text, f.SelectedValue.VNAME);
                tbVName.Text = f.SelectedValue.VNAME;
            }
            if (this.tbMFG.Text.isEmpty() && amk.MFGDate.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("MFG Date:{0}=>{1}", tbMFG.Text, amk.MFGDate);
                tbMFG.Text = amk.MFGDate;
            }

            if (VAR.BOOL[eVarBool.Opt_UserQtyRQ] == false && this.tbQTY.Text.isEmpty() && amk.QTY != 0)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("QTY:{0}=>{1}", tbQTY.Text, amk.QTY);

                PUB.log.Add($"Quantity updated {tbQTY.Text}->{amk.QTY}");
                tbQTY.Text = amk.QTY.ToString();
            }


            var custcode = amk.RID.Substring(2, 4);
            if (this.TbCustCode.Text.isEmpty() && custcode.isEmpty() == false)
            {
                msg += (msg.isEmpty() ? "" : "\n") + string.Format("QTY:{0}=>{1}", TbCustCode.Text, custcode);
                TbCustCode.Text = custcode;// amk.QTY.ToString();
            }

            if (msg.isEmpty() == false)
            {
                UTIL.MsgI("The following information has been changed\n" + msg, true);
            }
        }

        private void label2_Click_1(object sender, EventArgs e)
        {
            var sid = this.tbSID.Text.Trim();
            if (sid.isEmpty()) return;
            using (var db = new DataSet1TableAdapters.K4EE_Component_Reel_Print_InformationTableAdapter())
            {
                var dr = db.GetBySID(PUB.MCCode, sid).FirstOrDefault();
                if (dr == null || dr.PrintPosition.isEmpty())
                {
                    UTIL.MsgE("No print position stored for entered SID\n" +
                        "SID:" + sid);
                    return;
                }
                this.PrintPos = dr.PrintPosition;
            }

            DisplayPrintPos(this.PrintPos);
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            var sid = this.tbSID.Text.Trim();
            if (sid.isEmpty())
            {
                UTIL.MsgE("SID value is required");
                return;
            }
            func_CheckDateQty();
        }

        DateTime stime = DateTime.Now;
        private void tmAutoConfirm_Tick(object sender, EventArgs e)
        {
            var ts = DateTime.Now - stime;
            btOK.Text = string.Format("{0:N0}/{1:N0} 초후 자동 완료", ts.TotalSeconds, AR.SETTING.Data.Timeout_AutoConfirm);
            if (ts.TotalSeconds >= AR.SETTING.Data.Timeout_AutoConfirm)
            {
                tmAutoConfirm.Stop();
                autoconf = true;
                btOK.PerformClick();
            }
        }

        private void 회전기준바코드로설정ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvbcdList.FocusedItem == null)
            {
                UTIL.MsgE("No item has focus");
                return;
            }
            var dataindex = lvbcdList.FocusedItem.Index;
            foreach (ListViewItem item in this.lvbcdList.Items)
            {
                if (item.Index == dataindex) item.Checked = true;
                else item.Checked = false;
            }
        }

        private void button4_Click_1(object sender, EventArgs e)
        {
            if (tbpartno.Text.isEmpty()) tbpartno.Text = "N/A";
            else
            {
                var dlg = UTIL.MsgQ("Do you want to change the current Part No value to N/A?");
                if (dlg == DialogResult.Yes) tbpartno.Text = "N/A";
            }
        }

        private void linkLabel9_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(this.tbCustName, "INPUT CUST NAME");
        }

        private void button5_Click_1(object sender, EventArgs e)
        {
            var a = 1;
            var b = 0;
            var c = a / b;

        }

        private void lvbcdList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvbcdList.FocusedItem == null) toolStripStatusLabel1.Text = "--";
            toolStripStatusLabel1.Text = lvbcdList.FocusedItem.SubItems[1].Text;
        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }

        private void button5_Click_2(object sender, EventArgs e)
        {
            if (tbVName.Text.isEmpty()) tbVName.Text = "N/A";
            else
            {
                var dlg = UTIL.MsgQ("Do you want to change the current VenderName value to N/A?");
                if (dlg == DialogResult.Yes) tbVName.Text = "N/A";
            }
        }

        private void tbBarcode_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                var data = tbBarcode.Text.Trim().Split(';');
                if (data.Length > 4)
                {
                    if (data[0].Length == 9 && data[0].StartsWith("10"))
                    {
                        var sid = data[0].Trim();
                        var batch = data[1].Trim();
                        var cpn = data[4].Trim();

                        if (tbBatch.Text.isEmpty())
                        {
                            tbBatch.Text = batch;
                            PUB.log.Add($"Set batch value from user barcode input:{batch}");
                        }


                        if (tbSID.Text.isEmpty())
                        {
                            tbSID.Text = sid;
                            tbpartno.Text = cpn;
                            PUB.log.Add($"Enter SID/Part number from user barcode, value:{sid}{cpn}");
                        }
                        else
                        {
                            if (tbSID.Text.StartsWith("103"))
                            {
                                //검증
                                if (tbSID.Text.Equals(sid))
                                {
                                    //맞다
                                    tbpartno.Text = cpn;
                                    PUB.log.Add($"Enter part number from user barcode, value:{cpn}");
                                }
                                else
                                {
                                    UTIL.MsgE($"Part number not set due to 103 SID mismatch\nOriginal SID: {tbSID.Text}\nTarget SID: {sid}");
                                }
                            }
                            else if (tbSID.Text.StartsWith("101"))
                            {
                                //변경전 101->103
                                lbSID0.Text = tbSID.Text.Trim();
                                tbSID.Tag = tbSID.Text.Trim();
                                tbSID.Text = sid;
                                tbpartno.Text = cpn;
                                PUB.log.Add($"Enter SID/Part number from user barcode, value:{sid}{cpn}");
                            }
                        }
                    }
                    else PUB.log.AddE($"User barcode 0 is not SID{data}");
                }
                else PUB.log.AddE($"User barcode error insufficient array count:{data}");
                tbBarcode.SelectAll();
                tbBarcode.Focus();
            }
        }

        private void lnkBatch_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbBatch, "INPUT BATCH");
        }

        private void linkLabel10_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            UTIL.TouchKeyShow(tbQtyMax, "INPUT MAX QTY(SAP)");
        }
    }
}
