using Emgu.CV;
using Emgu.CV.Structure;
using Euresys.Open_eVision_2_11;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using UIControl;

namespace Project
{

	public partial class fMain : Form
	{
		string[] 방위 = new string[] { "↙", "↓", "↘", "←", "→", "↖", "↑", "↗" };
		//Label[] lbs_p0 = null;
		//Label[] lbs_p1 = null;
		//Label[] lbs_p2 = null;

		//Label[] lbs_a0 = null;
		//Label[] lbs_a1 = null;
		//Label[] lbs_a2 = null;


		Boolean bRunConnection = true;
		System.Threading.Thread thConnection;   //연결체크
		byte ConnectSeq = 0;
		DateTime AirOffStart = DateTime.Parse("1982-11-23");
		DateTime EmergencyTime = DateTime.Now;
		Dialog.fLog logForm = null;

		public fMain()
		{
			InitializeComponent();
			Pub.initCore();
			AddLiveviewControl();

			ivs = new arCtl.ImageBox[] { iv0, null, iv2 };
			this.KeyDown += (s1, e1) =>
			{
				if (e1.KeyCode == Keys.Escape) this.Close();
				else if (e1.KeyCode == Keys.F1 && e1.Control && e1.Shift)
				{
					Boolean debug = Pub.flag.get(eFlag.DEBUG);
					Pub.flag.set(eFlag.DEBUG, !debug, "FMAIN_SECRETKEY");
					ShowDebugMenu();
				}
				else if (e1.KeyCode == Keys.F2 && e1.Control && e1.Shift) menu_logform();
				else if (e1.KeyCode == Keys.F5) btStart.PerformClick();
				else if (e1.KeyCode == Keys.F8) btJobCancle.PerformClick();
				else if (e1.KeyCode == Keys.F9) btStart.PerformClick();

				if (DateTime.Now > Pub.LastInputTime) Pub.LastInputTime = DateTime.Now;
			};

			//dotList = new List<arCtl.arLabel>();
			//dotList.AddRange(new arCtl.arLabel[] { lbDot1, lbDot2, lbDot3, lbDot4, lbDot5, lbDot6, lbDot7, lbDot8, lbDot9, lbDot10 });

			this.MouseMove += (s1, e1) => { if (DateTime.Now > Pub.LastInputTime) Pub.LastInputTime = DateTime.Now; };
			this.FormClosing += __Closing;

			if (Pub.setting.FullScreen) this.WindowState = FormWindowState.Maximized;
			else this.Size = new Size(1280, 1024);

			//this.lbTitle.MouseMove += LbTitle_MouseMove;
			//this.lbTitle.MouseUp += LbTitle_MouseUp;
			//this.lbTitle.MouseDown += LbTitle_MouseDown;
			//this.lbTitle.DoubleClick += LbTitle_DoubleClick;
		}

		void ShowDebugMenu()
		{
			Boolean debug = Pub.flag.get(eFlag.DEBUG);
			this.btDebug.Visible = debug;
			this.loader1.arDebugMode = debug;
			//this.rtStatusMessage.Visible = debug;
			//this.panel1.Visible = debug;
		}

		private void __Closing(object sender, FormClosingEventArgs e)
		{
			Pub.popup.needClose = true;
			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				Util.MsgE("동작 중에는 종료 할 수 없습니다.");
				e.Cancel = true;
				return;
			}
			if (Pub.sm.Step < StateMachine.eSMStep.CLOSING)
			{
				var rlt = Util.MsgQ(Lang.Q_EXIT);
				if (rlt != System.Windows.Forms.DialogResult.Yes)
				{
					e.Cancel = true;
					return;
				}
				_Close_Start();
			}
		}

		void UpdateLogTextColor()
		{
			this.logTextBox1.ColorList = new arCtl.sLogMessageColor[] {
				new arCtl.sLogMessageColor("BARCODE",Color.Magenta),
				new arCtl.sLogMessageColor("ERR",Color.Red),
				new arCtl.sLogMessageColor("NORMAL", Color.WhiteSmoke),
				new arCtl.sLogMessageColor("WARN", Color.Tomato),
				new arCtl.sLogMessageColor("INFO", Color.SkyBlue),
				new arCtl.sLogMessageColor("VIS", Color.Blue),
			};
		}

		void RefreshList()
		{
			if (Pub.setting.OnlineMode == false) return;

			if (this.InvokeRequired)
			{
				this.BeginInvoke(new MethodInvoker(RefreshList));
				return;
			}

			try
			{
				var dtstr = DateTime.Now.ToShortDateString();
				if(Pub.setting.STDLabelFormat7) this.ta.FillByLen7(this.dataSet1.Component_Reel_Result, dtstr, dtstr);
				else this.ta.Fill(this.dataSet1.Component_Reel_Result, dtstr, dtstr);
				foreach (DataGridViewRow item in this.arDatagridView1.Rows)
				{
					var vloc = item.Cells["dvc_loc"].Value;
					var sloc = vloc == null ? string.Empty : vloc.ToString();
					if (sloc == "L")
						item.DefaultCellStyle.BackColor = Color.FromArgb(220, 220, 220);
					else
						item.DefaultCellStyle.BackColor = Color.FromArgb(250, 250, 250);

				}
				Pub.log.AddI(string.Format("목록 새로 고침({0}건)", dataSet1.Component_Reel_Result.Count));
			}
			catch (Exception ex)
			{
				Pub.log.AddE("목록 새로고침 실패:" + ex.Message);
			}
		}
		private void __Load(object sender, EventArgs e)
		{


			this.Text = Application.ProductName + " ver " + Application.ProductVersion;
			Pub.init(); //public initialize

			UpdateLogTextColor();
			Pub.log.RaiseMsg += Log_RaiseMsg;
			Pub.logWS.RaiseMsg += LogWS_RaiseMsg;

			//위치 레이아웃 off한다.
			//this.pPosL.Visible = false;
			//this.pPosC.Visible = false;
			//this.pPosR.Visible = false;

			this.Show();
			//  sbDevice.Text = "";
			SetStatusMessage(0, "프로그램 초기화", Color.White, Color.White, Color.Tomato, Color.Black);



			//피커 상태초기화
			foreach (var item in this.loader1.arVar_Picker)
				item.Clear();

			//포트 상태 초기화
			foreach (var item in this.loader1.arVar_Port)
				item.Clear();


			Pub.flag.set(eFlag.DEBUG, true, "개발중");
			ShowDebugMenu();

			////'Application.DoEvents();

			//setting dio events
			Pub.dio.IOValueChanged += Dio_IOValueChanged;
			Pub.dio.Message += dio_IOMessage;

			//setting mot events
			Pub.mot.Message += mot_Message;
			Pub.mot.HomeStatusChanged += mot_HomeStatusChanged;
			Pub.mot.AxisMoveValidateCheck += mot_AxisMoveValidateCheck;
			Pub.mot.PositionChanged += Mot_PositionChanged;
			Pub.mot.StatusChanged += mot_StatusChanged;
			Pub.mot.EndStatusChanged += Mot_EndStatusChanged;

			//remote control
			Pub.remocon = new arDev.RS232("R");
			Pub.remocon.Terminal = arDev.RS232.eTerminal.LF;
			//Pub.remocon.ReceiveData += remocon_ReceiveData;
			var portinfo = Pub.setting.Serial_Remocon.Split(':');
			Pub.remocon.PortName = portinfo[0];
			if (portinfo.Length > 1) Pub.remocon.BaudRate = int.Parse(portinfo[1]);
			else Pub.remocon.BaudRate = 9600;
			if (Pub.remocon.Open() == false) Pub.log.AddAT("디버깅포트 열기 실패(" + Pub.setting.Serial_Remocon + ")");
			else Pub.log.Add("디버깅포트 열기 성공(" + Pub.setting.Serial_Remocon + ")");


			//clear 
			ClearBarcode();

			Pub.sm.SetMsgOptOff(); //모든 메세지출력을 해제한다. (이벤트는 동작함)

			Pub.log.Add("State Machine Start");
			Pub.sm.StepChanged += sm_StepChanged;
			Pub.sm.Message += sm_Message;
			Pub.sm.Running += sm_Running;
			Pub.sm.SPS += sm_SPS;
			Pub.sm.Start();



			//Fag 값 변화
			Pub.flag.ValueChanged += Flag_ValueChanged;

			//ILock 값 변화
			Pub.LockPKT.ValueChanged += Lock_ValueChanged;
			Pub.LockPKX.ValueChanged += Lock_ValueChanged;
			Pub.LockPKZ.ValueChanged += Lock_ValueChanged;
			Pub.LockPLM.ValueChanged += Lock_ValueChanged;
			Pub.LockPLZ.ValueChanged += Lock_ValueChanged;
			Pub.LockPRL.ValueChanged += Lock_ValueChanged;
			Pub.LockPRM.ValueChanged += Lock_ValueChanged;
			Pub.LockPRR.ValueChanged += Lock_ValueChanged;
			Pub.LockPRZ.ValueChanged += Lock_ValueChanged;
			Pub.LockVS0.ValueChanged += Lock_ValueChanged;
			Pub.LockVS1.ValueChanged += Lock_ValueChanged;
			Pub.LockVS2.ValueChanged += Lock_ValueChanged;

			loader1.ClearMenu();
			loader1.Message += loader1_Message;
			loader1.IConClick += loader1_IConClick;
			loader1.ButtonClick += Loader1_ButtonClick;


			UpdateUnloderInfo();

			///데이터버퍼(히스토리)
			//Pub.Result.JObHistory.PropertyChanged += JOBHistory_PropertyChanged;

			//연결체크용 쓰레드
			var thStart = new System.Threading.ThreadStart(bwDeviceConnection);
			thConnection = new System.Threading.Thread(thStart);
			thConnection.IsBackground = false;
			thConnection.Start();

			//조이스틱 설정
			Pub.joystick = new arDev.Joystick.JoystickRaw();
			Pub.joystick.Changed += Joystick_Changed;
			Pub.joystick.Connected += Joystick_Connected;
			Pub.joystick.Disconnected += Joystick_Disconnected;
			Pub.joystick.InputChanged += Joystick_InputChanged;
			if (Pub.setting.Jostick_pid != 0 && Pub.setting.Jostick_vid != 0)
			{
				Pub.log.Add($"Joystick Connect VID:{Pub.setting.Jostick_vid},PID:{Pub.setting.Jostick_pid}");
				Pub.joystick.Connect(Pub.setting.Jostick_vid, Pub.setting.Jostick_pid);
			}

			//키엔스연결
			InitBarcode();

			tmDisplay.Start(); //start Display

			Pub.AddSystemLog(Application.ProductVersion, "SCREEN", "Message");

			Pub.log.Add("Program Start");
			if (Pub.setting.OnlineMode)
				Pub.CheckNRegister3(Application.ProductName, "chi", Application.ProductVersion);

			if (Pub.setting.EnableDebugMode)
			{
				btDebug.Visible = true;
				Pub.flag.set(eFlag.DEBUG, true, "FMAIN_STARTUP");
				// menu_logform();
			}

			RefreshList();
		}

		//private void DispImage(int vIdx)
		//{
		//    Int32 bitsPerPixel = 0;
		//    Int32 stride = 0;
		//    PixelFormat pixelFormat = PixelFormat.Format8bppIndexed;
		//    //color
		//    bitsPerPixel = 8;
		//    stride = (Int32)((_width[vIdx] * bitsPerPixel + 7) / 8);
		//    using (var bitmap = new Bitmap(_width[vIdx], _height[vIdx], stride, pixelFormat, _pImage[vIdx]))
		//    {
		//        SetGrayscalePalette(bitmap);
		//        ivs[vIdx].Image = bitmap;
		//    }
		//}
		//void JOBHistory_PropertyChanged(object sender, PropertyChangedEventArgs e)
		//{
		//	if (this.InvokeRequired)
		//	{
		//		var p = new PropertyChangedEventArgs(e.PropertyName);
		//		this.BeginInvoke(new PropertyChangedEventHandler(JOBHistory_PropertyChanged), new object[] { sender, p });
		//		return;
		//	}

		//	if (e.PropertyName.ToUpper() == "ADD")
		//		Pub.log.Add(string.Format("JOB HISTORY CNT:{0},PROPERTY:{1}", Pub.Result.JObHistory.Count, e.PropertyName));

		//	var pname = e.PropertyName.Split(':');
		//	if (pname[0].ToLower() == "add")
		//	{
		//		var item = Pub.Result.JObHistory.Get(pname[1]);
		//		addListItem(item);
		//	}
		//	else if (pname[0].ToLower() == "remove")
		//	{
		//		//삭제
		//		var guid = pname[1]; //이 아이템을 제거해준다.
		//		this.lvJOB.Items.RemoveByKey(guid);
		//	}
		//	else if (pname[0].ToLower() == "clear")
		//	{
		//		this.lvJOB.Items.Clear();
		//	}
		//	else if (pname[0].ToLower() == "set")
		//	{
		//		var dr = Pub.Result.JObHistory.Get(pname[1]);
		//		UpdateListItem(dr);
		//	}
		//}

		//void addListItem(Class.JobData item)
		//{
		//	var lv = this.lvJOB.Items.Add(item.guid, item.No.ToString(), 0);
		//	lv.SubItems.Add(item.VisionData.MatchValidation ? "O" : "X");
		//	lv.SubItems.Add(item.JobStart.ToString("HH:mm:ss"));
		//	lv.SubItems.Add(item.VisionData.RID);
		//	lv.SubItems.Add(item.VisionData.SID);
		//	lv.SubItems.Add(item.VisionData.VLOT);
		//	lv.SubItems.Add(item.VisionData.QTY.ToString());
		//	lv.SubItems.Add(item.PortPos);
		//	lv.SubItems.Add(item.PrintPos);
		//	lv.SubItems.Add(item.VisionData.Angle.ToString());
		//	lv.SubItems.Add(item.VisionData.ZPL.isEmpty() ? "--" : "O");
		//	lv.SubItems.Add(item.Message);

		//	var visstr = string.Format("{2}",
		//		item.VisionData.STime,
		//		item.VisionData.ETime,
		//		item.VisionData.RunTime.TotalMilliseconds);

		//	lv.SubItems.Add(visstr);
		//	lv.SubItems.Add(item.VisionData.QRInputRaw);
		//	lv.SubItems.Add(item.VisionData.QROutRaw);
		//	lv.SubItems.Add(item.VisionData.ZPL);

		//	lv.Tag = item.guid;

		//	Color fColor, bColor;
		//	Pub.GetJobColor(item.error, lv.BackColor, out fColor, out bColor);
		//	lv.BackColor = bColor;
		//	lv.ForeColor = fColor;

		//	lv.EnsureVisible();
		//}
		//void UpdateListItem(Class.JobData item)
		//{
		//	//해당아이템을 찾아서 값을 변경 해준다
		//	var items = this.lvJOB.Items.Find(item.guid, false);
		//	if (items != null && items.Length > 0)
		//	{
		//		foreach (var lv in items)
		//		{
		//			int idx = 0;
		//			lv.SubItems[idx++].Text = item.No.ToString();//
		//			lv.SubItems[idx++].Text = item.VisionData.MatchValidation ? "O" : "X";
		//			lv.SubItems[idx++].Text = item.JobStart.ToString("HH:mm:ss") + "(" + item.JobRun.TotalSeconds.ToString("N0") + ")";
		//			lv.SubItems[idx++].Text = item.VisionData.RID;
		//			lv.SubItems[idx++].Text = item.VisionData.SID;
		//			lv.SubItems[idx++].Text = item.VisionData.VLOT;
		//			lv.SubItems[idx++].Text = item.VisionData.QTY.ToString();
		//			lv.SubItems[idx++].Text = item.PortPos;
		//			lv.SubItems[idx++].Text = item.PrintPos;
		//			lv.SubItems[idx++].Text = item.VisionData.Angle.ToString();
		//			lv.SubItems[idx++].Text = item.VisionData.ZPL.isEmpty() ? "--" : "O";
		//			lv.SubItems[idx++].Text = item.Message;

		//			var visstr = string.Format("{2}",
		//				item.VisionData.STime,
		//				item.VisionData.ETime,
		//				item.VisionData.RunTime.TotalMilliseconds);

		//			lv.SubItems[idx++].Text = visstr;
		//			lv.SubItems[idx++].Text = item.VisionData.QRInputRaw;
		//			lv.SubItems[idx++].Text = item.VisionData.QROutRaw;
		//			lv.SubItems[idx++].Text = item.VisionData.ZPL;


		//			Color fColor, bColor;
		//			Pub.GetJobColor(item.error, lv.BackColor, out fColor, out bColor);
		//			lv.BackColor = bColor;
		//			lv.ForeColor = fColor;

		//		}
		//	}
		//}

		void loader1_Message(object sender, Loader.MessageArgs e)
		{
			//로더에서 발생한 메세지
			if (e.isError) Pub.log.AddE(e.Message);
			else Pub.log.Add(e.Message);
		}

		private void Log_RaiseMsg(DateTime LogTime, string TypeStr, string Message)
		{
			this.logTextBox1.AddMsg(LogTime, TypeStr, Message);
		}
		private void LogWS_RaiseMsg(DateTime LogTime, string TypeStr, string Message)
		{
			this.logTextBox1.AddMsg(LogTime, TypeStr, Message);
		}

		void bwDeviceConnection()
		{
			while (bRunConnection)
			{
				if (ConnectSeq == 0)
				{
					var tscam = DateTime.Now - CameraConTimeL;
					if (tscam.TotalSeconds > 7)
					{
						//if (Pub.setting.EnableExtVision)
						if (Pub.wsL == null || Pub.wsL.Connected == false)
						{
							if (Pub.setting.Log_CameraConn)
								Pub.log.Add($"카메라 접속 시도{Pub.setting.HostIPL}:{Pub.setting.HostPortL}");
							if (Pub.wsL != null)
							{
								DetachCameraEventL(); //이벤트 종료
								Pub.wsL.Dispose();
							}

							Pub.wsL = new WatsonWebsocket.WatsonWsClient(Pub.setting.HostIPL, Pub.setting.HostPortL, false);
							AttachCameraEventL();
							Pub.wsL.Start();
							CameraConTimeL = DateTime.Now;
						}
						else
						{
							//연결이 되어있다면 상태값을 요청한다
							if(Pub.flag.get(eFlag.RDY_CAMERA_L)==false)
							{
								WS_Send(0, Pub.wsL, Guid.NewGuid().ToString(), "STATUS");
								CameraConTimeL = DateTime.Now.AddSeconds(-4);
							}
						}
					}
					ConnectSeq += 1;
				}
				else if (ConnectSeq == 1)
				{
					var tscam = DateTime.Now - CameraConTimeR;
					if (tscam.TotalSeconds > 7)
					{
						//if (Pub.setting.EnableExtVision)
						if (Pub.wsR == null || Pub.wsR.Connected == false)
						{
							if (Pub.setting.Log_CameraConn)
								Pub.log.Add($"카메라 접속 시도{Pub.setting.HostIPR}:{Pub.setting.HostPortR}");
							if (Pub.wsR != null)
							{
								DetachCameraEventR(); //이벤트 종료
								Pub.wsR.Dispose();
							}

							Pub.wsR = new WatsonWebsocket.WatsonWsClient(Pub.setting.HostIPR, Pub.setting.HostPortR, false);
							AttachCameraEventR();
							Pub.wsR.Start();
							CameraConTimeR = DateTime.Now;
						}
						else
						{
							//연결이 되어있다면 상태값을 요청한다
							if (Pub.flag.get(eFlag.RDY_CAMERA_R) == false)
							{
								WS_Send(1, Pub.wsR, Guid.NewGuid().ToString(), "STATUS");
								CameraConTimeR = DateTime.Now.AddSeconds(-4);
							}
						}
					}
					ConnectSeq = 0;
				}
				System.Threading.Thread.Sleep(2000);
				//Console.WriteLine(DateTime.Now.ToString("mm:ss.fff") + " update loop");
			}

		}

		delegate void SelectModelHandler(string modelName);

		void SelectModelM(string modelName)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new SelectModelHandler(SelectModelM), new object[] { modelName });
				return;
			}

			//초기화
			Pub.Result.mModel.ReadValue(modelName);
			if (Pub.Result.mModel.isSet)
			{
				Pub.log.AddAT("모션모델선택완료 : " + Pub.Result.mModel.Title);

				//사용한 모델이름을 저장함
				if (Pub.uSetting.LastModelM != Pub.Result.mModel.Title)
				{
					Pub.uSetting.LastModelM = Pub.Result.mModel.Title;
					Pub.uSetting.Save();
				}
			}
			else
			{
				Pub.log.AddE("모션모델선택실패(없는모델명:" + modelName + ")");
			}
		}

		void SelectModelV(string modelName)
		{
			//
			if (this.InvokeRequired)
			{
				this.Invoke(new SelectModelHandler(SelectModelV), new object[] { modelName });
				return;
			}

			//초기화
			Pub.Result.vModel.Title = string.Empty;
			var modelVision = Pub.mdm.GetDataV(modelName);
			if (modelVision != null)
			{
				var mv = Pub.Result.vModel;
				mv.ReadValue(modelVision); //Util.CopyData(model, Pub.Result.vModel);                
				Pub.log.AddAT("모델선택완료 : " + mv.Title);


				//선택한 모델을 저장함
				if (Pub.uSetting.LastModelV != mv.Title)
				{
					Pub.uSetting.LastModelV = mv.Title;
					Pub.uSetting.Save();
				}

				if (mv.UnitCount.X == 0) mv.UnitCount.Offset(1, 0);
				if (mv.UnitCount.Y == 0) mv.UnitCount.Offset(0, 1);
				if (mv.VisionCount.X == 0) mv.VisionCount.Offset(mv.UnitCount.X, 0);
				if (mv.VisionCount.Y == 0) mv.VisionCount.Offset(0, mv.UnitCount.Y);
				if (mv.DotFontSize == 0) mv.DotFontSize = 10;
			}
			else
			{

				Pub.log.AddE("모델선택실패(없는모델명:" + modelName + ")");
			}

		}

		void UpdateSoftLimit()
		{
			Pub.log.Add("update UpdateSoftLimit");
			//181219 softlimit
			//double softLimit = 0;
			//Boolean armForward = Util_DO.GetIOInput(eDIName.F_CHECK_ARM_FWD);

			//if (Pub.Result.Model.waferSize.StartsWith("8"))
			//{
			//    if (armForward) softLimit = Pub.system.SWLimit8A;
			//    else softLimit = Pub.system.SWLimit8;

			//    if (softLimit != 0)
			//    {
			//        Pub.mot.SetSoftLimit(0, true, softLimit, -softLimit);
			//        Pub.log.AddI(string.Format("(8') Y-Axis Soft Limit : {0}mm", softLimit));
			//    }
			//    else
			//    {
			//        Pub.mot.SetSoftLimit(0, false, 0, 0);
			//        Pub.log.AddI(string.Format("(8') Y-Axis Soft Limit - Off"));
			//    }
			//}
			//else if (Pub.Result.Model.waferSize.StartsWith("12"))
			//{
			//    if (armForward) softLimit = Pub.system.SWLimit12A;
			//    else softLimit = Pub.system.SWLimit12;

			//    if (softLimit != 0)
			//    {
			//        Pub.mot.SetSoftLimit(0, true, softLimit, -softLimit);
			//        Pub.log.AddI(string.Format("(12') Y-Axis Soft Limit : {0}mm", softLimit));
			//    }
			//    else
			//    {
			//        Pub.mot.SetSoftLimit(0, false, 0, 0);
			//        Pub.log.AddI(string.Format("(12') Y-Axis Soft Limit - Off"));
			//    }
			//}
		}


		void ColorChange(arCtl.arLabel contorls, bool value, Color tColor, Boolean isBG = true)
		{
			if (isBG)
			{
				if (value == true)
				{
					if (contorls.BackColor != tColor) contorls.BackColor = tColor;
				}
				else
				{
					if (contorls.BackColor != Color.Gray) contorls.BackColor = Color.Gray;
				}
			}
			else
			{
				if (value == true)
				{
					if (contorls.ForeColor != tColor) contorls.ForeColor = tColor;
				}
				else
				{
					if (contorls.ForeColor != Color.Gray) contorls.ForeColor = Color.Gray;
				}
			}
		}
		void ColorChange2(arCtl.arLabel contorls, bool value, Color tColor)
		{
			if (value == true)
			{
				if (contorls.BackColor2 != tColor) contorls.BackColor2 = tColor;
			}
			else
			{
				if (contorls.BackColor2 != Color.Gray) contorls.BackColor2 = Color.Gray;
			}
		}
		void ColorChange(arCtl.arLabel contorls, bool value, Color tColor, Color fColor, Boolean isBG = true)
		{
			if (isBG)
			{
				if (value == true)
				{
					if (contorls.BackColor != tColor) contorls.BackColor = tColor;
				}
				else
				{
					if (contorls.BackColor != fColor) contorls.BackColor = fColor;
				}
			}
			else
			{
				if (value == true)
				{
					if (contorls.ForeColor != tColor) contorls.ForeColor = tColor;
				}
				else
				{
					if (contorls.ForeColor != fColor) contorls.ForeColor = fColor;
				}
			}
		}

		void func_sw_initialize()
		{
			Pub.Result.ResetButtonDownTime = DateTime.Now;
			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				Pub.popup.setMessage("SYSTEM INNITIALIZE\n" +
					"동작중에는 [초기화]를 실행할 수 없습니다\n" +
					"방법 #1 => [중지] 버튼을 이용하여 시스템을 정지 후 다시 시도\n" +
					"방법 #2 => [수동실행] 모드로 전환 후 다시 시도");
			}
			else if (
				Pub.sm.getNewStep != StateMachine.eSMStep.RESET &&
				Pub.sm.Step != StateMachine.eSMStep.RESET)
			{
				Pub.log.Add("시스템상태를 RESET으로 전환 합니다");
				Pub.AddSystemLog(Application.ProductVersion, "MAIN", "SYSTEM RESET");
				Pub.sm.setNewStep(StateMachine.eSMStep.RESET);
			}
			else Pub.log.AddAT("RESET 중이므로 RESET 버튼을 무시 합니다.");
		}

		void func_sw_errorclear()
		{
			//RESET 버튼 눌렸을때 공통 처리 사항
			Util_DO.SetBuzzer(false); //buzzer off

			if (Pub.popup.Visible)
				Pub.popup.needClose = true;

			if (
				loader1.Scean == Loader.eScean.xmove)
				loader1.Scean = UIControl.Loader.eScean.Nomal;

			//팝업메세지가 제거가능한 메세지라면 없앤다.
			if (loader1.HasPopupMenu && loader1.PopupMenuRequireInput == false)
				loader1.DelMenu();

			//알람클리어작업(모션에 오류가 있는 경우에만)
			if (Pub.mot.IsInit && Pub.mot.hasServoAlarm)
			{
				Pub.mot.SetAlarmClearOn();
				System.Threading.Thread.Sleep(200);
				Pub.mot.SetAlarmClearOff();
			}

			//자재가 없고, 센서도 반응안하는데. 진공이 되어잇으면 off한다
			if (Util_DO.isVacOKL() == 0 && Pub.flag.get(eFlag.PK_ITEMON) == false && Util_DO.GetIOOutput(eDOName.PICK_VAC1) == false)
				Util_DO.SetPickerVac(false, true);


			//중단, 오류 모드일때에는 이 리셋이 의미가 있다.
			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				Pub.log.Add("동작중에는 [RESET] 버튼이 동작하지 않습니다");
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.PAUSE || Pub.sm.Step == StateMachine.eSMStep.OVERLOAD)
			{
				//시작대기상태로 전환(대기상태일때 시작키를 누르면 실행 됨)
				Pub.sm.setNewStep(StateMachine.eSMStep.WAITSTART);
				Pub.log.AddAT("Reset Clear System Resume & Pause ON");
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.EMERGENCY)
			{
				Pub.popup.setMessage("EMERGENCY RESET\n" +
						"[비상정지] 상태에는 [시스템초기화] 를 실행 해야 합니다\n" +
						"상단메뉴 [초기화] 를 실행하세요");

				Pub.log.Add("RESET버튼으로 인해 EMG 상황에서 IDLE전환");
				Pub.sm.setNewStep(StateMachine.eSMStep.IDLE);
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.ERROR)
			{
				Pub.log.Add("RESET버튼으로 인해 ERR 상황에서 IDLE전환");
				Pub.sm.setNewStep(StateMachine.eSMStep.IDLE);
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.WAITSTART)
			{
				//시작대기중일때에도 아무 처리안함
				//Pub.log.Add("시작버튼대기중에는 [RESET] 버튼이 동작하지 않습니다");
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.IDLE)
			{
				//Pub.log.Add("대기중에는 [RESET] 버튼이 동작하지 않습니다");
			}
			else
			{
				//Pub.log.AddE("정의되지 않은 상태에서의 REST 키 버튼 입력 - 대기상태로 전환합니다");
				Pub.sm.setNewStep(StateMachine.eSMStep.IDLE);
			}
		}

		/// <summary>
		/// 작업시작전 작업에대한 선택
		/// </summary>
		void fucn_start_job_select()
		{
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new MethodInvoker(fucn_start_job_select), null);
			}
			else
			{
				//로그창 지우기
				if (this.logTextBox1.InvokeRequired) logTextBox1.BeginInvoke(new Action(() => { logTextBox1.Clear(); }));
				else this.logTextBox1.Clear();

				Pub.popup.needClose = true;
				//Pub.flag.set(eFlag.RUN_INIT, false, "FN_JOBSELECT");
				Pub.ClearRunStep(0);
				Pub.ClearRunStep(1);

				if (Pub.mot.IsInit == false)
				{
					Pub.log.AddE("모션 보드가 초기화 되지 않았습니다.\n문의 바랍니다");
					return;
				}
				else if (Pub.dio.IsInit == false)
				{
					Pub.log.AddE("I/O 보드가 초기화 되지 않았습니다.\n문의 바랍니다");
					return;
				}
				else if (Pub.mot.hasHomeSetOff == true)
				{
					Pub.log.AddE("홈 검색이 완료되지 않은 축이 있습니다.\n장치초기화를 먼저 실행 하세요");
					return;
				}

				//작업형태를 선택하게 한다
				var f = new Dialog.fSelectJob();
				if (f.ShowDialog() == DialogResult.OK)
				{
					UpdateUnloderInfo();
					LoadSeqSIDHistory();
					Pub.sm.setNewStep(StateMachine.eSMStep.RUN);
				}
				else
				{
					Pub.log.AddAT("작업 시작전 선택화면에서 사용자가 취소함");

				}
			}
		}

		/// <summary>
		/// 입력차수에 따른 릴 수량 목록을 가져온다
		/// </summary>
		void LoadSeqSIDHistory()
		{
			//해당 차수의 전체 sidhistory 를 가져와야한다
			//System.Diagnostics.Stopwatch wat = new Stopwatch();
			//wat.Restart();
			//Pub.Result.SIDHistory.Clear();
			//var SIDHistoryFiles = Pub.dbmSidHistory.Getfiles(Pub.Result.JobSeqDate, Pub.Result.JobSeqNo);
			//var DT = Pub.dbmSidHistory.GetDatas(SIDHistoryFiles);
			//Pub.Result.SIDHistory.Merge(DT);
			//Pub.Result.SIDHistory.AcceptChanges();
			//wat.Stop();
			//Pub.log.AddI(string.Format("SID 불러오기시간:{0}ms,Cnt:{1}", wat.ElapsedMilliseconds, Pub.Result.SIDHistory.Count));
		}


		void func_sw_start()
		{
			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				//아무것도 하지 않는다
				Pub.log.Add("동작중에는 START 버튼이 사용되지 않습니다");
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.IDLE)   //일반대기상태
			{
				if (Util_DO.isVacOKL() > 0)
				{
					Util_DO.SetBuzzer(true);
					Pub.popup.setMessage("PICKER ITEM DETECT\nPICKER 에서 아이템이 감지되었습니다\n[작업취소] 를 눌러서 아이템을 DROP 한 후 제거해주세요.");
					return;
				}
				else if (Util_DO.getCartSize(1) == eCartSize.None)
				{
					Util_DO.SetBuzzer(true);
					Pub.popup.setMessage("로더에 카트가 장착되지 않았습니다");
					return;
				}
				else if (Util_DO.GetIOInput(eDIName.PORT1_LIM_DN) == true && Util_DO.GetIOInput(eDIName.PORT1_DET_UP) == true)
				{
					//하단리밋과, 자재감지가 동시에 들어오면 overload 이다
					Util_DO.SetBuzzer(true);
					Pub.popup.setMessage("로더에 너무 많은 릴이 적재 되어 있습니다\n" +
						"하단 리밋 센서와 상단 릴 감지 센서가 동시에 확인 됩니다");
					return;
				}
				//else if (Util_DO.getCartSize(0) == eCartSize.None && Util_DO.getCartSize(2) == eCartSize.None)
				//{
				//	Util_DO.SetBuzzer(true);
				//	Pub.popup.setMessage("언로더에 카트가 장착되지 않았습니다");
				//	return;
				//}

				fucn_start_job_select();


			}
			else if (Pub.sm.Step == StateMachine.eSMStep.WAITSTART) //시작대기상태
			{

				Util_DO.SetRoomLight(false);

				//새로시작하면 포트 얼라인을 해제 해준다
				Pub.flag.set(eFlag.RDY_PORT_PL, false, "SW_START");
				Pub.flag.set(eFlag.RDY_PORT_PC, false, "SW_START");
				Pub.flag.set(eFlag.RDY_PORT_PR, false, "SW_START");

				//얼라인 상태를 모두 초기화 한다
				//loader1.arVar_Port.ToList().ForEach(t => t.AlignOK = 0);

				//언로더 체크작업은 항상 다시 시작한다
				if (Pub.Result.UnloaderSeq > 1) Pub.Result.UnloaderSeq = 1;

				//팝업메세지가 사라지도록 한다
				Pub.popup.needClose = true;
				Pub.sm.setNewStep(StateMachine.eSMStep.RUN);
				Pub.log.Add("[사용자 일시정지] 해제 => 작업이 계속됩니다");
			}
			else
			{
				string msg = "SYSTEM {0}\n[RESET] 버튼을 누른 후 다시 시도하세요";
				msg = string.Format(msg, Pub.sm.Step);
				Pub.popup.setMessage(msg);
			}
		}

		void func_sw_stop()
		{
			//매거진 투입모터 멈춤
			if (Util_DO.GetIOOutput(eDOName.PORT0_MOT_RUN)) Util_DO.SetPortMotor(0, eMotDir.CW, false, "Button Stop");
			if (Util_DO.GetIOOutput(eDOName.PORT1_MOT_RUN)) Util_DO.SetPortMotor(1, eMotDir.CW, false, "Button Stop");
			if (Util_DO.GetIOOutput(eDOName.PORT2_MOT_RUN)) Util_DO.SetPortMotor(2, eMotDir.CW, false, "Button Stop");

			//자재가 없고, 센서도 반응안하는데. 진공이 되어잇으면 off한다
			if (Util_DO.isVacOKL() == 0 && Pub.flag.get(eFlag.PK_ITEMON) == false && Util_DO.GetIOOutput(eDOName.PICK_VAC1) == true)
				Util_DO.SetPickerVac(false, true);

			//조명켜기
			if (Pub.setting.Disable_RoomLight == false)
				Util_DO.SetRoomLight(true);

			//모든 모터도 멈춘다
			if (Pub.mot.hasMoving) Pub.mot.MoveStopAll("Stop Button");

			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				//일시중지상태로 전환한다
				Pub.Result.SetResultMessage(eResult.OPERATION, eECode.USER_STOP, eNextStep.pause);
				Pub.log.Add("[사용자 일시정지]");
			}
			else if (Pub.sm.Step == StateMachine.eSMStep.HOME)   //홈진행중에는 대기상태로 전환
			{
				Pub.ClearRunStep(0);
				Pub.ClearRunStep(1);
				Pub.sm.setNewStep(StateMachine.eSMStep.IDLE);
			}

			//로그 기록
			Pub.LogFlush();
		}

		void ClearBarcode()
		{
			//Pub.Result.Clear();
			//Pub.log.AddI("Clear Barcode");
		}

		private void toolStripButton1_Click(object sender, EventArgs e)
		{
			if (Pub.isRunning)
			{
				//실 동작중이면 사용하지 못하게 함
				Pub.popup.setMessage("MAPCHECK ERROR\n" +
					"동작중에는 [맵확인] 기능을 사용할 수 없습니다\n" +
					"[STOP] 으로 일시정지 후 다시 시도하세요");
				return;
			}

		}


		Dialog.SystemParameter frmSysParam = null;
		private void systemParameterToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (frmSysParam == null || frmSysParam.IsDisposed || frmSysParam.Disposing)
			{
				if (frmSysParam != null) frmSysParam.FormClosed -= frmSysParam_FormClosed;
				frmSysParam = new Dialog.SystemParameter();
				frmSysParam.FormClosed += frmSysParam_FormClosed;
			}
			frmSysParam.Show();
			frmSysParam.Activate();
			if (frmSysParam.WindowState == FormWindowState.Minimized)
				frmSysParam.WindowState = FormWindowState.Normal;
		}

		void frmSysParam_FormClosed(object sender, FormClosedEventArgs e)
		{
			var f = sender as Form;
			if (f.DialogResult == System.Windows.Forms.DialogResult.OK)
			{
				UpdateSoftLimit();
			}
		}


		private void buzzerTestToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Util_DO.SetBuzzer(true);
		}

		void CheckFreeSpace()
		{
			try
			{
				double freeSpaceRate_ = 0;
				var path = Pub.getSavePath(out freeSpaceRate_);
				if (path.StartsWith("\\"))
				{
					loader1.arFreespace = 0.0;
				}
				else
				{
					loader1.arFreespace = freeSpaceRate_;//
					if (freeSpaceRate_ < Pub.setting.AutoDeleteThreshold)
					{
						Pub.flag.set(eFlag.MINSPACE, true, "CheckFreeSpace");
						loader1.arLowDiskSpace = true;
					}
					else
					{
						Pub.flag.set(eFlag.MINSPACE, false, "CheckFreeSpace");
						loader1.arLowDiskSpace = false;
					}
				}
			}
			catch (Exception ex)
			{
				loader1.arFreespace = 0.0;
				Pub.log.AddE("check free space : " + ex.Message);
			}
		}

		private void demoRunToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.Result.JobEndTime = DateTime.Now;

		}


		private void arLabel2_Click_1(object sender, EventArgs e)
		{
			var ctl = sender as arCtl.arLabel;
			if (ctl.Enabled == false) return;
			Pub.log.Add("User Click : Start", false);
			func_sw_start();
		}



		private void arLabel4_Click_1(object sender, EventArgs e)
		{
			Pub.log.Add("User Click : Stop", false);
			func_sw_stop();
		}



		private void openMapFileToolStripMenuItem_Click(object sender, EventArgs e)
		{
			OpenFileDialog od = new OpenFileDialog();
			if (od.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

		}

		void mapV_DragDrop(object sender, DragEventArgs e)
		{
			string[] files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
			if (files == null || files.Length < 1) return;

		}

		void mapV_DragEnter(object sender, DragEventArgs e)
		{
			e.Effect = DragDropEffects.All;
		}


		Color getStatecolor(string State)
		{
			if (State == "U") return Color.DimGray;
			else if (State == "I") return Color.SkyBlue;
			else if (State == "O") return Color.Yellow;
			else return Color.Tomato;
		}



		private void sbReset_Click(object sender, EventArgs e)
		{
			func_sw_errorclear();
		}

		private void btReset_Click(object sender, EventArgs e)
		{
			Pub.log.Add("User Click : Reset", false);
			func_sw_errorclear();
		}




		private void setZValidToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.mot.isHomeSet[(int)eAxis.Z_THETA] = true;
			Pub.log.Add("user set z-home set on");
		}



		private void toolStripButton4_Click(object sender, EventArgs e)
		{
			Util_DO.ToggleRoomLight();
		}



		private void gridviewTestToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var task = new System.Threading.Tasks.Task(new Action(() =>
			{
				Random rnd = new Random();
				var startTime = DateTime.Now;
				while ((DateTime.Now - startTime).TotalSeconds <= 180)
				{


				}

			}));
			task.Start();
		}

		private void errorToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.popup.setMessage("error\berror message");
		}

		private void informationToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.popup.setMessage("info\ninformation message", MessageWindow.eWindowType.information);
		}

		private void attentionToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.popup.setMessage("attention\nattention message", MessageWindow.eWindowType.attention);
		}


		private void showDevInfo()
		{
			Util.MsgI("개발 : K4-장비기술팀 1파트\n" +
				"설치 : 2020-01-17\n" +
				"H/W : 임현 (Hyeon.Im@amkor.co.kr, T.8549)\n" +
				"S/W : 김치균 (Chikyun.kim@amkor.co.kr, T.8567)");
		}

		private void btHistory_ButtonClick(object sender, EventArgs e)
		{
			var file = System.IO.Path.Combine(Util.CurrentPath, "ResultView.exe");
			if (System.IO.File.Exists(file) == false)
			{
				Pub.popup.setMessage("Result Viewer Error\n결과보기 파일이 존재하지 않습니다\n개발자에 문의 주세요(T.8567)\nFile : " + file);
				return;
			}
			Util.RunProcess(file);
		}

		private void toolStripButton9_Click(object sender, EventArgs e)
		{
			var file = System.IO.Path.Combine(Util.CurrentPath, "LogView.exe");
			if (System.IO.File.Exists(file) == false)
			{
				Pub.popup.setMessage("Log Viewer Error\n로그보기 파일이 존재하지 않습니다\n개발자에 문의 주세요(T.8567)\nFile : " + file);
				return;
			}

			Util.RunProcess(file, Pub.log.BaseDirectory + " ERROR");
		}

		private void toolStripMenuItem3_Click(object sender, EventArgs e)
		{

		}

		private void toolStripMenuItem6_Click(object sender, EventArgs e)
		{
			//save image
			var sd = new SaveFileDialog();
			sd.Filter = "jpeg(*.jpg)|*.jpg";
			if (sd.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
			//this.orgImage.Save(sd.FileName);
			Util.RunExplorer(sd.FileName);
		}



		private void initializeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (Pub.isRunning)
			{
				Pub.popup.setMessage("AUTORUN MODE\n자동 실행중에는 실행 할 수 없습니다");
				return;
			}
			Pub.ClearRunStep(0);
			Pub.ClearRunStep(1);
			Pub.flag.set(eFlag.UserStepCheck, true, "initializeToolStripMenuItem_Click");
			//Pub.preStep = Pub.sm.Step;
			//if (Pub.preStep == StateMachine.eSMStep.PAUSE) Pub.preStep = StateMachine.eSMStep.RUN;

			//수작업으로 이동 제한값을 초기화해준다. (안그러면 모션 이동으로인한 오류 발생함)
			for (int i = 0; i < 6; i++)
				Pub.Result.PreventMotionPosition[i] = Pub.mot.LastMoveCmdPos[i];


			var ctl = sender as ToolStripMenuItem;
			if (ctl.Tag == null) return;
			var tagstr = ctl.Tag.ToString();

			eRunStep newstep = eRunStep.NOTSET;
			switch (tagstr)
			{
				case "0":
					newstep = eRunStep.STARTCHKSW;
					break;
				case "1":
					newstep = eRunStep.STARTCHKHW;
					break;
				case "2":
					newstep = eRunStep.INITIALHW;
					break;
				case "3":
					newstep = eRunStep.PORTLOAD;
					break;
				case "10":
					Pub.flag.set(eFlag.UserStepCheck, true, "initializeToolStripMenuItem_Click");
					newstep = eRunStep.BEGINPICK;
					break;
				case "11":  //prev Camera Position move

					newstep = eRunStep.BEGINPICK;
					break;
				case "12":  //next Camera Position move

					newstep = eRunStep.BEGINPICK;
					break;
			}
			Pub.setNewRunStep(0, newstep);
			Pub.sm.setNewStep(StateMachine.eSMStep.RUN);
		}

		private void setHomeSetToolStripMenuItem_Click(object sender, EventArgs e)
		{
			for (int i = 0; i < 6; i++)
			{
				Pub.mot.isHomeSet[i] = true;
				Pub.mot.HomeSetTime[i] = DateTime.Now;
				Pub.mot.HomeResult[i] = arDev.AzinAxt.AXT_MOTION_HOME_RESULT.HOME_SUCCESS;
				Pub.log.AddAT("manual home set");
			}

		}
		void menu_logform()
		{
			if (logForm == null || logForm.IsDisposed == true || logForm.Disposing == true)
				logForm = new Dialog.fLog();
			if (logForm.WindowState == FormWindowState.Minimized) logForm.WindowState = FormWindowState.Normal;
			logForm.Show();
		}


		private void toolStripMenuItem9_Click(object sender, EventArgs e)
		{
			menu_logform();
		}

		private void tsMenu_Paint(object sender, PaintEventArgs e)
		{

			var c2 = Color.FromArgb(40, 40, 40);
			var c1 = Color.FromArgb(80, 80, 80);
			//c1 = Color.Gold;
			//c2 = Color.DarkOrange;

			var br = new System.Drawing.Drawing2D.LinearGradientBrush(e.ClipRectangle,
				c1, c2,
				System.Drawing.Drawing2D.LinearGradientMode.Vertical);


			e.Graphics.FillRectangle(br, e.ClipRectangle);
			br.Dispose();

		}

		//#region "Mouse Form Move"

		//private Boolean fMove = false;
		//private Point MDownPos;

		//private void LbTitle_DoubleClick(object sender, EventArgs e)
		//{
		//	if (this.WindowState == FormWindowState.Maximized) this.WindowState = FormWindowState.Normal;
		//	else this.WindowState = FormWindowState.Maximized;
		//	//this.loader1.RemakeRect();
		//}
		//private void LbTitle_MouseMove(object sender, MouseEventArgs e)
		//{
		//	if (fMove)
		//	{
		//		Point offset = new Point(e.X - MDownPos.X, e.Y - MDownPos.Y);
		//		this.Left += offset.X;
		//		this.Top += offset.Y;
		//		offset = new Point(0, 0);
		//	}
		//}
		//private void LbTitle_MouseUp(object sender, MouseEventArgs e)
		//{
		//	fMove = false;
		//}
		//private void LbTitle_MouseDown(object sender, MouseEventArgs e)
		//{
		//	MDownPos = new Point(e.X, e.Y);
		//	fMove = true;
		//}

		//#endregion

		private void button2_Click(object sender, EventArgs e)
		{
			this.WindowState = FormWindowState.Minimized;
		}

		private void button1_Click(object sender, EventArgs e)
		{
			if (this.WindowState == FormWindowState.Maximized)
				this.WindowState = FormWindowState.Normal;
			else
				this.WindowState = FormWindowState.Maximized;
		}

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



		private void 수량저장폴더ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var path = System.IO.Path.Combine(
				Pub.setting.Path_Data, "Count",
				DateTime.Now.Year.ToString("0000"));
			if (System.IO.Directory.Exists(path))
				Util.RunExplorer(path);
			else
				Util.RunExplorer(System.IO.Path.Combine(Pub.setting.Path_Data, "Count"));
		}


		private void arLabel4_Click(object sender, EventArgs e)
		{
			Pub.log.Add("user motion alarm clear");
			Pub.mot.SetAlarmClearOn();
			System.Threading.Thread.Sleep(500);
			Pub.mot.SetAlarmClearOff();
		}

		private void arLabel10_Click_1(object sender, EventArgs e)
		{
			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}

			this.Close();
		}

		private void button7_Click(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}
			var cur = Util_DO.GetIOOutput(eDOName.LAMPON1);
			Util_DO.SetRoomLight(!cur);
		}

		private void button3_Click(object sender, EventArgs e)
		{
			var file = System.IO.Path.Combine(Util.CurrentPath, "ResultView", "ResultView.exe");
			if (System.IO.File.Exists(file) == false)
			{
				Pub.popup.setMessage("Result Viewer Error\n결과보기 파일이 존재하지 않습니다\n개발자에 문의 주세요(T.8567)\nFile : " + file);
				return;
			}
			Util.RunProcess(file);
		}

		private void button4_Click(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}

			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}

			var f = new fModelM();
			if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				if (f.Value != "")
				{
					SelectModelM(f.Value);
				}
			}
		}


		private void button5_Click(object sender, EventArgs e)
		{
			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}

			var f = new fModelV();
			if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				if (f.Value != "")
				{
					SelectModelV(f.Value);
				}
			}
			f.Dispose();
		}

		private void button6_Click(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}
			//show io panerl
			var f = new Dialog.fIOMonitor();
			f.ShowDialog();
			f.Dispose();
		}

		private void arLabel8_Click(object sender, EventArgs e)
		{

		}

		private void button9_Click(object sender, EventArgs e)
		{

		}

		private void arLabel13_Click(object sender, EventArgs e)
		{
			Util.ScreenCaptrue(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height, new Point(0, 0));
		}

		private void button8_Click(object sender, EventArgs e)
		{

			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}

			var msg = new System.Text.StringBuilder();


			if (Pub.mot.hasHomeSetOff)
			{
				msg.AppendLine("! 장치 초기화가 완료되지 않은 상태입니다\n! 장치초기화를 실행 하세요");
			}

			if (Pub.isRunning == true)
			{
				msg.AppendLine("! " + Lang.CAN_NOT_RUN_AUTOMODE);
			}

			if (Pub.sm.Step == StateMachine.eSMStep.PAUSE)
			{
				msg.AppendLine("! RESET을 누른 후 다시 시도하세요");
			}

			if (Util_DO.isEmergencyOn() == true)
			{
				msg.AppendLine("! 비상정지를 해제하세요");
			}

			if (Util_DO.isSaftyDoorF() == false)
			{
				msg.AppendLine("!전면 도어가 열려 있습니다");
			}

			if (Util_DO.isSaftyDoorR() == false)
			{
				msg.AppendLine("!후면 도어가 열려 있습니다");
			}

			if (msg.Length > 0)
			{
				Util.MsgE(msg.ToString());
				Pub.log.AddE(msg.ToString());
				return;
			}

			msg.Clear();
			msg.AppendLine("Q. 작업을 취소하고 모션의 위치 초기화를 실행하시겠습니까?");
			var dlgresult = Util.MsgQ(msg.ToString());
			if (dlgresult != System.Windows.Forms.DialogResult.Yes) return;

			Pub.log.Add("User Click : tray out & clear position", false);
			Run_MotionPositionReset();

		}

		void Run_MotionPositionReset()
		{
			Pub.flag.set(eFlag.UserStepCheck, false, "Run_MotionPositionReset");
			Pub.log.AddAT("배출 및 원점이동 시작");
			Pub.updateRunStepSeq(0, 1);
			Pub.AddSystemLog(Application.ProductVersion, "MAIN", "작업취소");
			Pub.sm.setNewStep(StateMachine.eSMStep.POSITION_RESET);//실행모드로 변경
		}

		private void arLabel14_Click(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}
			var msg = new System.Text.StringBuilder();

			if (Pub.isRunning == true)
				msg.AppendLine("*" + Lang.CAN_NOT_RUN_AUTOMODE);

			if (Util_DO.isEmergencyOn() == true)
				msg.AppendLine("* 비상정지 상태일때에는 움직일 수 없습니다.");

			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
				msg.AppendLine("* 동작중에는 초기화할 수 없습니다");

			if (msg.Length > 0)
			{
				Util.MsgE(msg.ToString());
				return;
			}

			//CMenuButton btYes = new CMenuButton
			//{
			//    Text = "초기화",
			//    Tag = "yes",
			//    BackColor = Color.Tomato,
			//    OverColor = Color.Gold
			//};

			//CMenuButton btNo = new CMenuButton("취소", "NO");
			//var menu = new CMenu("모션의 홈 및 상태 초기화를 실행하시겠습니까?", "장치 초기화", "init", eMsgIcon.Alert, btYes, btNo);
			//loader1.AddMenu(menu);

			msg.Clear();
			msg.AppendLine("모션의 홈 및 상태의 초기화를 실행하시겠습니까?");
			var dlgresult = Util.MsgQ(msg.ToString());
			if (dlgresult != System.Windows.Forms.DialogResult.Yes) return;

			Pub.log.Add("User Click : initialize", false);
			func_sw_initialize();
		}

		private void arLabel11_Click(object sender, EventArgs e)
		{
			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}


			fSetting f = new fSetting();

			var popmsg = Pub.popup.Visible;
			if (f.ShowDialog() == DialogResult.OK)
			{

				UpdateUnloderInfo();

				Pub.initDIOSensitive();
				if (Pub.setting.Disable_RoomLight == true)
					Util_DO.SetRoomLight(false);
				if (Pub.setting.Disable_TowerLamp == true)
				{
					Util_DO.SetTwGrn(false);
					Util_DO.SetTwRed(false);
					Util_DO.SetTwYel(false);
				}
				if (Pub.setting.Serial_Remocon.isEmpty() == false)
				{
					var portinfo = Pub.setting.Serial_Remocon.Split(':');
					var portName = portinfo[0];
					int baud = 9600;
					if (portinfo.Length > 1) baud = int.Parse(portinfo[1]);
					if (Pub.remocon.PortName != portName)
					{
						Pub.remocon.Close();
						Pub.remocon.PortName = portName;
						Pub.remocon.BaudRate = baud;
						if (Pub.remocon.Open() == false)
							Pub.log.AddE("Remote Control Port Open Error : " + Pub.remocon.errorMessage);
					}
				}

				//프린터설정 - 201223
				Pub.PrinterL.printerName = Pub.setting.PrintLeftName;
				Pub.PrinterR.printerName = Pub.setting.PrintRightName;

				//if (Pub.setting.Disable_Axis1) Pub.mot.SetSVON(0, false);
				//if (Pub.setting.Disable_Axis0) Pub.mot.SetSVON(1, false);
				//if (Pub.setting.Disable_Axis2) Pub.mot.SetSVON(2, false);
				//if (Pub.setting.Disable_Axis3) Pub.mot.SetSVON(3, false);
				//if (Pub.setting.Disable_Axis4) Pub.mot.SetSVON(4, false);
				//if (Pub.setting.Disable_Axis5) Pub.mot.SetSVON(5, false);
				//if (Pub.setting.Disable_Axis6) Pub.mot.SetSVON(6, false);


			}
			if (popmsg) Pub.popup.Visible = true;
			Pub.ApplyZplCode();
		}

		private void arLabel12_Click(object sender, EventArgs e)
		{

			string file = System.IO.Path.Combine(Util.CurrentPath, "Manual", "index.htm");// "manual.pdf");
			if (System.IO.File.Exists(file) == false)
			{
				Util.MsgE("사용설명서 파일이 존재하지 않습니다\n" +
					"문의 : T8567 (장비기술 1파트)\n" +
					"파일명 : " + file);
				return;
			}
			Util.RunExplorer(file);
		}

		private void arLabel16_Click(object sender, EventArgs e)
		{
			arCtl.arLabel ctl = sender as arCtl.arLabel;
			this.cmOpenDir.Show(ctl, new Point((int)(ctl.Width / 1.5), (int)(ctl.Height / 1.5)));
		}

		private void 맵데이터보기ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Util.RunExplorer(Util.CurrentPath);
		}

		private void 저장폴더열기ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.LogFlush();
			var fi = new System.IO.FileInfo(Pub.log.FileName);
			Util.RunExplorer(fi.Directory.FullName);
		}

		private void 캡처ToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			string savefile = System.IO.Path.Combine(Util.CurrentPath, "ScreenShot", DateTime.Now.ToString("yyyyMMddHHmmss") + ".png");
			var grpath = new System.IO.FileInfo(savefile);
			Util.RunExplorer(grpath.Directory.FullName);
		}

		private void 저장ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var basepath = Pub.setting.GetPathData();
			var path = System.IO.Path.Combine(
				basepath, "History",
				DateTime.Now.Year.ToString("0000"),
				DateTime.Now.Month.ToString("00"),
				DateTime.Now.Day.ToString("00"));
			if (System.IO.Directory.Exists(path))
				Util.RunExplorer(path);
			else
				Util.RunExplorer(System.IO.Path.Combine(Pub.setting.Path_Data, "History"));
		}

		private void 이미지ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var basepath = Pub.setting.GetPathData();
			var path = System.IO.Path.Combine(
				basepath, "Images",
				DateTime.Now.Year.ToString("0000"),
				DateTime.Now.Month.ToString("00"),
				DateTime.Now.Day.ToString("00"));
			if (System.IO.Directory.Exists(path))
				Util.RunExplorer(path);
			else
				Util.RunExplorer(System.IO.Path.Combine(Pub.setting.Path_Data, "History"));
		}


		private void btDebug_Click(object sender, EventArgs e)
		{
			arCtl.arLabel ctl = sender as arCtl.arLabel;
			this.cmDebug.Show(ctl, new Point((int)(ctl.Width / 1.5), (int)(ctl.Height / 1.5)));
		}


		private void moveToZeroToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//var dlg = Util.MsgQ("모션의 위치 초기화를 실행하시겠습니까?");
			//if (dlg != System.Windows.Forms.DialogResult.Yes) return;
			////   return;


			//if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			//{
			//    Pub.popup.setMessage("SYSTEM INNITIALIZE\n" +
			//        "동작중에는 [원점이동]을 실행할 수 없습니다\n" +
			//        "방법 #1 => [중지] 버튼을 이용하여 시스템을 정지 후 다시 시도");
			//}
			//else if ( Pub.sm.getNewStep != StateMachine.eSMStep.QHOME && Pub.sm.Step != StateMachine.eSMStep.QHOME)
			//{
			//    Pub.log.Add("시스템상태를 Q-HOME으로 전환 합니다");
			//    Pub.sm.setNewStep(StateMachine.eSMStep.QHOME);
			//}
			//else Pub.log.AddAT("Q-HOME 중이므로 Q-HOME 기능을 무시 합니다");

		}


		Control FindContextSender(object sender)
		{
			var menuitem = sender as ToolStripMenuItem;
			if (menuitem != null)
			{
				var menu = menuitem.Owner as ContextMenuStrip;
				if (menu != null)
				{
					var selectedControl = menu.SourceControl;
					return selectedControl;
				}
			}
			return null;
		}


		private void lbTitleBS_Click(object sender, EventArgs e)
		{

		}

		private void lbTitleFS_Click(object sender, EventArgs e)
		{

		}

		private void sMResetToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}

			if (Pub.sm.Step != StateMachine.eSMStep.IDLE)
			{
				var dlg = Util.MsgQ(
					"프로그램 상태를 초기화 하시겠습니까?\n\n" +
					"진행 중인 사항은 모두 취소 됩니다.\n" +
					"필요한 경우 [시스템초기화] 가 필요할 수 있습니다");
				if (dlg != System.Windows.Forms.DialogResult.Yes) return;
			}
			else Pub.log.AddAT("대기상태일때에는 초기화 할 수 없습니다");

			Pub.log.Add("User Click : initialize", false);
			Pub.sm.setNewStep(StateMachine.eSMStep.IDLE, true);
			Pub.flag.set(eFlag.UserStepCheck, false, "sMResetToolStripMenuItem_Click");
		}


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

		private void motionEmulatorToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var f = new Dialog.fEmulator(Pub.mot, 7, 64, 64);
			Pub.mot.Emulator(f.devM);
			Pub.dio.Emulator(f.devIO);

			f.Show();
		}

		private void dIOEmulatorToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var f = new arDev.AzinAxt.Emulator.fEmulatorIO(64);
			Pub.dio.Emulator(f.devIO);
			f.Show();
			Console.WriteLine("emulator on");
		}

		private void dIOMonitorToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.dio.ShowMonitor();
		}

		private void refreshControklToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.loader1.RemakeRect();
			UpdateLogTextColor();

		}

		private void button3_Click_1(object sender, EventArgs e)
		{
			if (Pub.isRunning)
			{
				Pub.popup.setMessage("동작중에는 사용 불가");
				return;
			}
			if (Pub.sm.Step == StateMachine.eSMStep.PAUSE)
			{
				Util.MsgI("현재 중단 상태입니다.\n중단 메세지를 확인 하시고 RESET을 누른 후 다시 시도하세요");
				return;
			}


		}


		private void normalToolStripMenuItem_Click(object sender, EventArgs e)
		{
			loader1.Scean = UIControl.Loader.eScean.Nomal;
		}

		private void motorHomeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			loader1.Scean = UIControl.Loader.eScean.MotHome;
		}

		void UpdateUnloderInfo()
		{

		}

		private void toolStripMenuItem6_Click_1(object sender, EventArgs e)
		{
			var menu = sender as ToolStripMenuItem;
			var port = ushort.Parse(menu.Text);
		}


		private void btJobEnd_Click(object sender, EventArgs e)
		{

		}

		private void testToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//var newdr = new Class.JobData(0);
			//newdr.JobStart = Pub.Result.JobStartTime;
			//newdr.JobEnd = Pub.Result.JobEndTime;
			//newdr.No = Pub.Result.JObHistory.Count + 1;
			//newdr.error = Class.JobData.ErrorCode.None;
			//newdr.Message = "임시데이터";
			//newdr.VisionData = new Class.VisionData();
			//Pub.Result.JObHistory.Add(newdr);
		}


		void loader1_IConClick(object sender, UIControl.Loader.IconClickEventargs e)
		{
			//throw new NotImplementedException();
			Pub.log.Add("Loader Icon Click : " + e.item.Tag.ToString());
			if (e.item.Tag == "air")
			{
				var buttonOk = new CMenuButton("ON", "1");
				var buttonNo = new CMenuButton("OFF", "0");
				var newmenu = new CMenu("AIR 공급 상태를 변경 합니다", "AIR CONTROL", "air", eMsgIcon.Error, buttonOk, buttonNo)
				{
					BorderColor = Color.Gray,
				};
				loader1.AddMenu(newmenu);
			}

			else if (e.item.Tag == "emg")
			{
				btMReset.PerformClick();
			}

			else if (e.item.Tag == "debug")
			{
				Pub.flag.set(eFlag.DEBUG, !Pub.flag.get(eFlag.DEBUG), "");
				ShowDebugMenu();
			}
		}

		private void Loader1_ButtonClick(object sender, UIControl.Loader.MenuItemClickEventargs e)
		{
			//버튼이 눌렸으므로 해당 메뉴는 소거해준다
			Pub.log.Add("Menu Button Click : " + e.item.Tag);
			if (e.item.menutag == null)
			{
				//이곳은 메뉴가 아닌 일반 버튼이다
				if (e.item.Tag == "INPUTL")
				{

				}

				return;
			}
			else
			{
				switch (e.item.menutag)
				{
					case "init":
						if (e.item.Tag == "yes")
						{
							Pub.log.Add("User Click : initialize", false);
							func_sw_initialize();
						}
						break;
					case "sample":
						if (e.item.Tag == "1")
							Pub.log.Add("ok 버튼 클릭");
						else
							Pub.log.Add("no 버튼 클릭");
						break;

					case "air":
						if (e.item.Tag == "1")
						{
							Util_DO.SetAIR(true);
							Pub.log.Add("사용자 air on");
						}
						else
						{
							Util_DO.SetAIR(false);
							Pub.log.Add("사용자 air off");
						}
						break;
				}

			}

			//마지막메뉴를 제거한다
			loader1.DelMenu();
		}

		private void sampleToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var buttonOk = new CMenuButton("OK", "1");
			var buttonNo = new CMenuButton("CANCLE", "0");
			var newmenu = new CMenu("body str", "title", "sample", eMsgIcon.Error, buttonOk, buttonNo)
			{
				BorderColor = Color.Gray
			};
			loader1.AddMenu(newmenu);
		}

		private void debugModeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.loader1.arDebugMode = !this.loader1.arDebugMode;
			this.loader1.Invalidate();

		}

		private void lvJOB_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
		{


			e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(26, 26, 26)), e.Bounds);
			e.Graphics.DrawRect(e.Bounds, Color.FromArgb(64, 64, 64), 1);
			e.Graphics.DrawString(e.Header.Text, e.Font, new SolidBrush(Color.FromArgb(200, 200, 200)), e.Bounds, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });

		}

		private void lvJOB_DrawItem(object sender, DrawListViewItemEventArgs e)
		{
			e.DrawDefault = true;
		}

		private void lvJOB_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
		{
			e.DrawDefault = true;
		}

		private void addJobItemToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//Pub.Result.JObHistory.Add(new Class.JobData
			//{
			//	JobEnd = DateTime.Now,
			//	JobStart = DateTime.Now,
			//	VisionData = new Class.VisionData
			//	{
			//		VLOT = "LOT",
			//		RID = "rid",
			//		SID = "sid",
			//		FileNameL = string.Empty,
			//		FileNameU = string.Empty,
			//		Angle = 10,
			//		Complete = true,
			//		MANU = "manu",
			//		MFGDATE = "1982-11",
			//		QTY = "998",
			//		Ready = false,
			//		STime = DateTime.Now,
			//		ETime = DateTime.Now,
			//		GTime = DateTime.Now
			//	}
			//});
		}


		private void countToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var f = new Dialog.fDebug();
			f.TopMost = true;
			f.Show();
		}
		[DllImport("user32")]
		public static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
		[DllImport("user32.dll")]
		private static extern int SetActiveWindow(int hwnd);

		[DllImport("user32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		[DllImport("user32.dll")]
		private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
		private void button5_Click_1(object sender, EventArgs e)
		{

			var path = @"D:\Amkor\ReelMInput\update.exe";
			var prc = Util.CheckExistProcess("ReelMInput");
			if (prc == null)
			{
				Util.RunProcess(path);
			}
			else
			{
				SetForegroundWindow(prc.MainWindowHandle);
			}
		}

		#region "System Parameter"

		#region "Motion Parameter"
		private void axis0ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.mot.ShowParameter(0);
		}

		private void axis1ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.mot.ShowParameter(1);
		}

		private void axis2ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.mot.ShowParameter(2);
		}

		private void axis3ToolStripMenuItem_Click(object sender, EventArgs e)
		{

		}

		private void axis4ToolStripMenuItem_Click(object sender, EventArgs e)
		{

		}
		#endregion

		private void clearToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			loader1.ClearMenu();
		}

		#endregion

		private void processListToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Pub.log.Add("process list");
			foreach (var prc in System.Diagnostics.Process.GetProcesses())
			{
				if (prc.ProcessName.StartsWith("svchost")) continue;
				if (prc.ProcessName.Contains(".host")) continue;
				Pub.log.Add(prc.ProcessName);
			}
		}

		Boolean camliveBusy = false;

		Stopwatch watFps = new Stopwatch();
		Stopwatch watFps0 = new Stopwatch();
		Stopwatch watFps1 = new Stopwatch();
		Stopwatch watFps2 = new Stopwatch();

		Control GetContextOwnerControl(object sender)
		{
			var menuitem = sender as ToolStripMenuItem;
			if (menuitem != null)
			{
				var menu = menuitem.Owner as ContextMenuStrip;
				if (menu != null)
				{
					return menu.SourceControl;
				}
			}
			return null;
		}

		private void arLabel3_Click(object sender, EventArgs e)
		{

		}

		private void 작업선택화면ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var f = new Dialog.fDataBufferSIDRef();
			f.TopMost = true;
			f.Show();
		}

		private void button3_Click_2(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}
			if (Pub.isRunning == true)
			{
				Util.MsgE(Lang.CAN_NOT_RUN_AUTOMODE);
				return;
			}

			//if (mDebug.Visible == false && Pub.dio.IsInit == false)
			//{
			//    Pub.popup.setMessage("DIGITAL IN/OUT MODULE\n" +
			//        "오류로 인해 해당 장치가 초기화되지 않았습니다\n" +
			//        "Ezconfig AXT 프로그램으로 H/W를 점검하세요");
			//    return;
			//}

			var f = new Dialog.QuickControl();
			f.StartPosition = FormStartPosition.CenterScreen;
			f.Show();
		}
		private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
		{

		}

		private void pictureBox1_Click(object sender, EventArgs e)
		{

			if (Pub.flag.get(eFlag.DEBUG) == true)
			{
				Pub.flag.set(eFlag.DEBUG, false, "개발중");
			}
			else
			{
				Pub.flag.set(eFlag.DEBUG, true, "개발중");
			}

			ShowDebugMenu();

		}

		private void cmCam_Opening(object sender, CancelEventArgs e)
		{
			if (Pub.sm.Step < StateMachine.eSMStep.IDLE)
				cmCam.Enabled = false;
			else
				cmCam.Enabled = true;
		}



		private void toolStripMenuItem2_Click(object sender, EventArgs e)
		{

			var selectContorol = GetContextOwnerControl(sender);
			if (selectContorol == null) return;
			var selectedtag = selectContorol.Tag.ToString();
			var vidx = int.Parse(selectedtag);

			SaveFileDialog sd = new SaveFileDialog();
			sd.Filter = "bitmap|*.bmp";
			sd.FileName = $"vision{vidx}.bmp";


			if (sd.ShowDialog() == DialogResult.OK)
			{
				if (vidx == 1)
				{
					SaveImage(sd.FileName);
				}
				else
				{
					if (this.OrgImage[vidx].Ptr == IntPtr.Zero)
					{
						Util.MsgE("이미지가 없습니다");
						return;
					}
					this.OrgBitmap[vidx].Save(sd.FileName);
				}

			}
		}

		private void saveImage2ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SaveFileDialog sd = new SaveFileDialog();
			sd.Filter = "bitmap|*.bmp";
			sd.FileName = "vision1.bmp";
			if (sd.ShowDialog() == DialogResult.OK)
			{
				//for (int i = 0; i < 3; i++)
				this.OrgBitmap[1].Save(sd.FileName);
			}
		}

		private void saveImage3ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SaveFileDialog sd = new SaveFileDialog();
			sd.Filter = "bitmap|*.bmp";
			sd.FileName = "vision2.bmp";
			if (sd.ShowDialog() == DialogResult.OK)
			{
				//for (int i = 0; i < 3; i++)
				this.OrgBitmap[2].Save(sd.FileName);
			}
		}

		private void sbVisTitle0_Click(object sender, EventArgs e)
		{
			iv0.ZoomFit();
			iv0.Invalidate();
		}

		private void sbVisTitle1_Click(object sender, EventArgs e)
		{
			//키엔스로부터 다운로드 받아서 처리해야함
			var tempfile = System.IO.Path.Combine(Util.CurrentPath, "Temp", "Keyence", DateTime.Now.ToString("HHmmss_fff") + ".bmp");
			var fi = new System.IO.FileInfo(tempfile);
			if (fi.Directory.Exists == false) fi.Directory.Create();
			this.iv1Keyence.DownloadRecentImage(fi.FullName);

		}

		private void sbVisTitle2_Click(object sender, EventArgs e)
		{
			iv2.ZoomFit();
			iv2.Invalidate();
		}

		//private void arLabel1_Click(object sender, EventArgs e)
		//{
		//}

		private void readBarcodeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//var selectContorol = GetContextOwnerControl(sender);
			//if (selectContorol == null) return;
			//var selectedtag = selectContorol.Tag.ToString();
			//var vidx = int.Parse(selectedtag);

			////선택된 아엩ㅇ믈 찾아야한다
			//if (Pub.sm.Step == StateMachine.eSMStep.IDLE || Pub.flag.get(eFlag.MOVE_PICKER) || Pub.sm.Step == StateMachine.eSMStep.HOME)
			//{
			//	string message;
			//	var data = Util_Vision.DetectQR_eVision(this.OrgImage[vidx], out message);

			//	if (message.isEmpty() == false)
			//		Pub.log.AddAT($"Vision {vidx} Message={message}");

			//	if (vidx == 0) { Util_Vision.DisplayQRData(data, Rectangle.Empty, iv0); }
			//	if (vidx == 1) { Util_Vision.DisplayQRData(data, Rectangle.Empty, null); }
			//	if (vidx == 2) { Util_Vision.DisplayQRData(data, Rectangle.Empty, iv2); }
			//}
			//else Util.MsgE("대기 상태일때 바코드 읽기가 가능합니다");
		}

		private void livetaskToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SetVisionTask();
			//Pub.flag.set(eFlag.LIVIEWVIEW0, true, "");
		}

		private void zoomFitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var selectContorol = GetContextOwnerControl(sender);
			if (selectContorol == null) return;
			var selectedtag = selectContorol.Tag.ToString();
			var vidx = int.Parse(selectedtag);

			if (vidx == 0) iv0.ZoomFit();
			// if (vidx == 1) iv1.ZoomFit();
			if (vidx == 2) iv2.ZoomFit();
		}

		private void keyenceTrigOnToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Trigger(true);
		}

		private void keyenceTrigOffToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Trigger(false);
		}

		private void keyenceSaveImageToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var fn = System.IO.Path.Combine(Util.CurrentPath, "Images", "keyence.bmp");
			SaveImage(fn);
		}

		private void arLabel29_Click(object sender, EventArgs e)
		{

		}

		private void arLabel20_Click(object sender, EventArgs e)
		{

		}

		private void button3_Click_3(object sender, EventArgs e)
		{
			if (Pub.sm.Step == StateMachine.eSMStep.RUN)
			{
				Pub.log.AddE("동작 중에는 사용할 수 없습니다");
				return;
			}
			Util_DO.SetPortMotor(1, eMotDir.CCW, true, "하강");
		}

		private void button4_Click_1(object sender, EventArgs e)
		{
			//이미지저장한다.
			if (Pub.sm.Step != StateMachine.eSMStep.RUN && Pub.sm.Step != StateMachine.eSMStep.PAUSE && Pub.sm.Step != StateMachine.eSMStep.WAITSTART)
			{
				var tempfil = System.IO.Path.Combine(Util.CurrentPath, "Temp", "keyence.bmp");
				var fi = new System.IO.FileInfo(tempfil);
				if (fi.Directory.Exists == false) fi.Directory.Create();
				this.iv1Keyence.DownloadRecentImage(fi.FullName);
				Pub.Result.ItemData[1].VisionData.SetImage(new Image<Gray, byte>(fi.FullName));
			}
			var f = new Dialog.fLoaderInfo(Pub.Result.ItemData[1].VisionData.bcdMessage);
			f.ShowDialog();
		}

		private void lbSize1_Click(object sender, EventArgs e)
		{
			//reset 기능
			Pub.Result.ItemData[1].VisionData.Clear("USER UI CLICK", true);
			Pub.flag.set(eFlag.END_VISION1, false, "USER UI CLICK");
		}

		bool liveviewprocesson = false;
		private void liveViewProcessOnOffToolStripMenuItem_Click(object sender, EventArgs e)
		{
			liveviewprocesson = !liveviewprocesson;
		}

		private void lbLock2_Click(object sender, EventArgs e)
		{
			var ctl = sender as arCtl.arLabel;
			var index = int.Parse(ctl.Tag.ToString());
			//	bool cur = false;

			if (Pub.isRunning)
			{
				Util.MsgE("동작중에는 카트교환을 할 수 없습니다\n'STOP' 버튼을 누른 후 다시 시도하세요");
				return;
			}

			bool curMag = Util_DO.GetIOOutput(eDOName.CART_MAG0);
			bool curLim = Util_DO.GetIOInput(eDIName.PORT0_LIM_DN);
			if (index == 1)
			{
				curMag = Util_DO.GetIOOutput(eDOName.CART_MAG1);
				curLim = Util_DO.GetIOInput(eDIName.PORT1_LIM_DN);
			}
			else if (index == 2)
			{
				curMag = Util_DO.GetIOOutput(eDOName.CART_MAG2);
				curLim = Util_DO.GetIOInput(eDIName.PORT2_LIM_DN);
			}

			//		cur = Util_DO.GetIOOutput(eDOName.CART_MAG0);
			if (curMag == false)
			{
				Pub.log.Add($"MAGNET{index} ON by USER");
				Util_DO.SetPortMagnet(index, true); //켜는건 바로 할 수 있게 한다
			}
			else
			{
				if (curLim == false)
				{
					Util.MsgE("포트를 모두 내린 후 다시 시도하세요");
					Util_DO.SetPortMotor(index, eMotDir.CCW, true, "카트교환"); //포트를 자동으로 내려준다
					return;
				}
				Util_DO.SetPortMagnet(index, false);
				Pub.log.Add($"MAGNET{index} OFF by USER");
			}
		}

		private void arLabel75_Click(object sender, EventArgs e)
		{
			//왼쪽검증취소
			if (Pub.sm.Step <= StateMachine.eSMStep.IDLE)
			{
				Util.MsgE("동작 중에만 처리 가능합니다");
				return;
			}
			if (Pub.flag.get(eFlag.RDY_VISION0) == false)
			{
				Util.MsgE("비젼 확인 중이 아닙니다");
				return;
			}
			Pub.Result.ItemData[0].VisionData.ValidSkipbyUser = true;
			Pub.log.AddE("사용자가 왼쪽 QR검증 기능을 SKIP했습니다");
		}


		private void arLabel73_Click(object sender, EventArgs e)
		{
			//오른쪽검증취소
			if (Pub.sm.Step <= StateMachine.eSMStep.IDLE)
			{
				Util.MsgE("동작 중에만 처리 가능합니다");
				return;
			}
			if (Pub.flag.get(eFlag.RDY_VISION0) == false)
			{
				Util.MsgE("비젼 확인 중이 아닙니다");
				return;
			}
			Pub.Result.ItemData[2].VisionData.ValidSkipbyUser = true;
			Pub.log.AddE("사용자가 오른쪽 QR검증 기능을 SKIP했습니다");
		}

		private void arLabel74_Click(object sender, EventArgs e)
		{
			//왼쪽재출력
			if (Pub.sm.Step == StateMachine.eSMStep.PAUSE)
			{
				Util.MsgE("일시중지 상태입니다 'RESET'키를 누른 후 다시 시도하세요");
				return;
			}
			if (Pub.sm.Step != StateMachine.eSMStep.WAITSTART)
			{
				Util.MsgE("작업시작대기 상태일때에만 사용이 가능합니다");
				return;
			}
			Pub.flag.set(eFlag.OK_PRINTL, false, "MOY_PY");
			Pub.flag.set(eFlag.RUN_PRINTL, true, "MOY_PY");
			Pub.flag.set(eFlag.SET_DATA_PORT0, true, "MOT_PX");
			Pub.flag.set(eFlag.PORTL_ITEMON, true, "item_pickoff"); //포트에 놓았다
			loader1.arVar_Port[0].AlignReset();
		}

		private void arLabel77_Click(object sender, EventArgs e)
		{
			//우측재출력
		}

		private void arDatagridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
		{
			//
		}

		private void arLabel6_Click(object sender, EventArgs e)
		{
			//포트내림
			if (Pub.isRunning)
			{
				Util.MsgE("동작중에는 사용할 수 없습니다");
				return;
			}
			var index = int.Parse((sender as arCtl.arLabel).Tag.ToString());
			if (Util_DO.GetPortMotorRun(index) == true) Util_DO.SetPortMotor(index, eMotDir.CW, false, "UI");
			else
			{
				if (Util.MsgQ("포트를 내릴까요?") == DialogResult.Yes)
					Util_DO.SetPortMotor(index, eMotDir.CCW, true, "UI포트내림");
			}
		}

		private void arLabel11_Click_1(object sender, EventArgs e)
		{
			//포트올림
			if (Pub.isRunning)
			{
				Util.MsgE("동작중에는 사용할 수 없습니다");
				return;
			}
			var index = int.Parse((sender as arCtl.arLabel).Tag.ToString());
			if (Util_DO.GetPortMotorRun(index) == true) Util_DO.SetPortMotor(index, eMotDir.CCW, false, "UI");
			else
			{
				if (Util.MsgQ("포트를 올릴까요?") == DialogResult.Yes)
					Util_DO.SetPortMotor(index, eMotDir.CW, true, "UI");
			}
		}

		private void arLabel64_Click(object sender, EventArgs e)
		{
			menu_logform();
		}

		private void 새로고침ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			RefreshList();
		}

		private void toolStripButton1_Click_1(object sender, EventArgs e)
		{
			RefreshList();
		}

		private void jObEndToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (Pub.flag.get(eFlag.INIT_MOTIO) == false)
			{
				Util.MsgE("모션이 초기화 되지 않았습니다\n잠시 후 다시 시도하세요");
				return;
			}
			ShowSummaryForm();
		}

		private void button3_Click_4(object sender, EventArgs e)
		{
			if (Pub.isRunning)
			{
				Util.MsgE("동작중에는 사용할 수 없습니다");
				return;
			}

			if (Pub.flag.get(eFlag.MOVE_PICKER))
			{
				Util.MsgE("해당 창이 열려 있습니다");
			}
			else
			{
				var f = new Dialog.fPickerMove();
				f.ShowDialog();

				//홈이 안잡혀있고, 센서가 중앙에 있다면 초기화를 묻는다
				if (Pub.mot.hasHomeSetOff == true && Util_DO.GetIOInput(eDIName.PICKER_SAFE))
				{
					btMReset.PerformClick();
				}

				RefreshList();
			}
		}

		private void jOBStartToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var f = new Dialog.fSelectJob();
			f.ShowDialog();
		}

		private void panel41_Paint(object sender, PaintEventArgs e)
		{

		}

		private void panel42_Paint(object sender, PaintEventArgs e)
		{

		}

		private void visionTrigger0ToolStripMenuItem_Click(object sender, EventArgs e)
		{

			//모든 큐를 제거한다.
			lock (BarcodeQueL)
			{
				while (BarcodeQueL.IsEmpty == false)
					BarcodeQueL.TryDequeue(out string msg);
				Pub.log.Add($"[0]큐제거 완료");
			}


			if (Pub.Result == null || Pub.Result.ItemData[0] == null)
			{
				Pub.flag.set(eFlag.RDY_VISION0, true, "USER");
				Pub.flag.set(eFlag.PRC_VISION0, false, "user");
				WS_Send(0, Pub.wsL, Guid.NewGuid().ToString(), "BCDIN");
			}
			else
			{
				Pub.flag.set(eFlag.RDY_VISION0, true, "USER");
				Pub.flag.set(eFlag.PRC_VISION2, false, "user");
				WS_Send(0, Pub.wsL, Pub.Result.ItemData[0].guid, "BCDIN");
			}


		}

		private void visionTrigger1ToolStripMenuItem_Click(object sender, EventArgs e)
		{

			//모든 큐를 제거한다.
			lock (BarcodeQueR)
			{
				while (BarcodeQueR.IsEmpty == false)
					BarcodeQueR.TryDequeue(out string msg);
				Pub.log.Add($"[1]큐제거 완료");
			}


			if (Pub.Result == null || Pub.Result.ItemData[2] == null)
			{
				Pub.flag.set(eFlag.RDY_VISION2, true, "USER");
				WS_Send(1, Pub.wsR, Guid.NewGuid().ToString(), "BCDIN");
			}

			else
			{
				Pub.flag.set(eFlag.RDY_VISION2, true, "USER");
				WS_Send(1, Pub.wsR, Pub.Result.ItemData[2].guid, "BCDIN");
			}

		}
		public enum CmdShow
		{
			Hide,
			Normal,
			Minimized,
			Maximized,
			NoActivate,
			Show,
			Minimize,
			MinimizeNoActive,
			NA,
			Restore,
			Default,
			ForceMinimize
		}
		private void button1_Click_1(object sender, EventArgs e)
		{
			if (Pub.wsL != null && Pub.wsL.Connected)
			{
				Util.MsgI("현재 프로그램이 연결되어 있습니다");
				return;
			}

			//카메라 l실행
			if (Pub.setting.CameraLFile.isEmpty() == true)
			{
				Util.MsgE("바코드 프로그램 파일명이 지정되지 않았습니다", true);
				return;
			}

			var fi = new System.IO.FileInfo(Pub.setting.CameraLFile);
			if (fi.Exists == false)
			{
				Util.MsgE("비젼 프로그램 파일이 존재하지 않습니다\n" + fi.FullName);
				return;
			}

			//var prc = null;// Util.CheckExistProcess("CrevisQRCode");
			//if (prc == null)
			{
				//Util.MsgI("바코드 프로그램을 새로 실행 했습니다\n잠시만 기다리면 실행 됩니다");
				Util.RunProcess(fi.FullName);
			}
			//else
			//{

			//	SetActiveWindow((int)prc.MainWindowHandle);
			//	SetForegroundWindow(prc.MainWindowHandle);
			//	ShowWindow(prc.MainWindowHandle, (int)CmdShow.Normal);
			//}
		}

		private void button2_Click_1(object sender, EventArgs e)
		{
			if (Pub.wsR != null && Pub.wsR.Connected)
			{
				Util.MsgI("현재 프로그램이 연결되어 있습니다");
				return;
			}


			//카메라 l실행
			if (Pub.setting.CameraRFile.isEmpty() == true)
			{
				Util.MsgE("바코드 프로그램 파일명이 지정되지 않았습니다", true);
				return;
			}

			var fi = new System.IO.FileInfo(Pub.setting.CameraRFile);
			if (fi.Exists == false)
			{
				Util.MsgE("비젼 프로그램 파일이 존재하지 않습니다\n" + fi.FullName);
				return;
			}

			//var prc = null;// Util.CheckExistProcess("CrevisQRCode");
			//if (prc == null)
			{
				//Util.MsgI("바코드 프로그램을 새로 실행 했습니다\n잠시만 기다리면 실행 됩니다");
				Util.RunProcess(fi.FullName);
			}
			//else
			//{

			//	SetActiveWindow((int)prc.MainWindowHandle);
			//	SetForegroundWindow(prc.MainWindowHandle);
			//	ShowWindow(prc.MainWindowHandle, (int)CmdShow.Normal);
			//}
		}

		private void visionProcess0ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			WS_Send(0, Pub.wsL, Guid.NewGuid().ToString(), "STATUS");
		}

		private void visionProcess1ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			WS_Send(1, Pub.wsR, Guid.NewGuid().ToString(), "STATUS");
		}

        private void customerRuleToolStripMenuItem_Click(object sender, EventArgs e)
        {


		}
    }


}