using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
	public partial class FMain
	{

		/// <summary>
		/// 로더용 포트 조작
		/// </summary>
		/// <param name="idx"></param>
		/// <param name="isFirst"></param>
		/// <param name="StepTime"></param>
		void _SM_RUN_MOT_PORT(int idx, Boolean isFirst, TimeSpan StepTime)
		{
            //포트 비활성 체크
            eVarBool FG_RDY_PORT;
			eDIName DI_LIMUP, DI_DETUP;
			eDOName DO_PORTRUN;
			Boolean PORT_DISABLE;

			//인덱스에 맞는 플래그와 DI값 설정
			if (idx == 0)
			{
				PORT_DISABLE = AR.SETTING.Data.Disable_PortL || AR.SETTING.Data.Disable_Left;
				FG_RDY_PORT = eVarBool.FG_RDY_PORT_PL; DI_DETUP = eDIName.PORTL_DET_UP;
				DI_LIMUP = eDIName.PORTL_LIM_UP; DO_PORTRUN = eDOName.PORTL_MOT_RUN;
			}
			else if (idx == 1)
			{
				PORT_DISABLE = AR.SETTING.Data.Disable_PortC;
				FG_RDY_PORT = eVarBool.FG_RDY_PORT_PC; DI_DETUP = eDIName.PORTC_DET_UP;
				DI_LIMUP = eDIName.PORTC_LIM_UP; DO_PORTRUN = eDOName.PORTC_MOT_RUN;
			}
			else
			{
				PORT_DISABLE = AR.SETTING.Data.Disable_PortR || AR.SETTING.Data.Disable_Right;
				FG_RDY_PORT = eVarBool.FG_RDY_PORT_PR; DI_DETUP = eDIName.PORTR_DET_UP;
				DI_LIMUP = eDIName.PORTR_LIM_UP; DO_PORTRUN = eDOName.PORTR_MOT_RUN;
			}

			//포트가 비활성화되어있다면 DETECT ON하고 , LIMIT는 해제한다 -201224
			if (PORT_DISABLE)
			{
				if (PUB.flag.get(FG_RDY_PORT) == false)
                    PUB.flag.set(FG_RDY_PORT, true, "DISABLE PORT");
				this.hmi1.arVar_Port[idx].AlignOK = 1;
                hmi1.arVar_Port[idx].errorCount = 0;
                return;
            }


			//비활성화(좌/우 기능사용여부확인)
			//if (idx == 0 && COMM.SETTING.Data.Disable_Left == true)
			//{
			//	this.hmi1.arVar_Port[idx].AlignOK = 1;
			//	return;
			//}
			//else if (idx == 2 && COMM.SETTING.Data.Disable_Right == true)
			//{
			//	this.hmi1.arVar_Port[idx].AlignOK = 1;
			//	return;
			//}


			//오류가 일정횟수 발생하면 RDY를 풀어준다(이경우에는 오류처리를 해서 알림을 해야할듯함!)
			if (hmi1.arVar_Port[idx].errorCount > 5)
			{
				if (hmi1.arVar_Port[idx].AlignOK != 1) hmi1.arVar_Port[idx].AlignOK = 1;
				if (PUB.flag.get(FG_RDY_PORT) == true) PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
				return;
			}

			//동작중에 X가 pICK 위치에 있다면. Z축이 홈인지 체크한다.
			if (PUB.sm.Step == eSMStep.RUN)
			{
				var PKZ_UNSAFE = MOT.getPositionOffset(eAxis.PZ_PICK, MOT.GetPZPos(ePZLoc.READY).Position) > 2;
				//var PKX_POS = MOT.GetPKX_PosName();
				var BSTOP = false;

				//Z축이 Ready 위치보다 낮게 있다면 멈추게한다
				if (idx == 0 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFL)) && PKZ_UNSAFE) BSTOP = true;
				else if (idx == 1 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKON)) && PKZ_UNSAFE) BSTOP = true;
				else if (idx == 2 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFR)) && PKZ_UNSAFE) BSTOP = true;
				if (BSTOP)
				{
					if (DIO.GetIOOutput(DO_PORTRUN) == true) DIO.SetPortMotor(idx, eMotDir.CCW, false, "Z-NOTREADY");
					return;
				}
			}

			var PORTALIGN_OK = hmi1.arVar_Port[idx].AlignOK;
			if (PORTALIGN_OK != 1) //align이 진행되지 않았다면 align을 잡기위해 처리를 해줘야한다
			{
                if (idx != 1)
                {
                    //
                }
                   
				//안전센서동작여부 확인
				var BSafty = DIO.isSaftyDoorF(idx, true);

				//안전이 확보된 경우에만 얼라인 ok를한다 - 임시로 해제를 한다?  상단리밋에 걸리것을 처리안하려는 코드인듯!
				//if (isPortDetUp(idx) == false && isPortLimUP(idx) == true && BSafty == true) PORTALIGN_OK = 1;

				if (PORTALIGN_OK == 0) //얼라인이 완료되지 않은상태라면 모터 하강
				{
					//모터하강시작시간
					PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;

					//리밋이 감지된 상태에서 작업하는거면 좀더 오래 내린다
					//if (isPortLimUP(idx))
					//{
					if (idx == 1) PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeL;
					else PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeU;

					//좌우측음 좀 덜 내려간다
					//}
					//else Pub.Result.PortAlignWaitSec[idx] = 1.2f;
					//Pub.Result.PortAlignWaitSec[idx] -= 1.0f; //1초제거  210108

					//모터하강
					if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
					{
						DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
						System.Threading.Thread.Sleep(100);
					}

					DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");

					//하강검사시작
					hmi1.arVar_Port[idx].AlignOK = 2;
					//Pub.log.AddAT($"포트({idx}) 얼라인(DOWN) 작업 시작");

					//포트가 이제 안정화하지 않았으니 안정화를 풀어준다
					PUB.flag.set(FG_RDY_PORT, false, "MOT_PORT_ALIGNSTART");
				}
				else if (PORTALIGN_OK == 2) //하강해서 찾는중
				{
					//자재감지센서가 감지안되고 일정시간이 지나면 정방향으로 전환한다
					if (isPortDetUp(idx) == false)
					{
						var waitSec = PUB.Result.PortAlignWaitSec[idx];
						var ts = new TimeSpan(DateTime.Now.Ticks - PUB.Result.PortAlignTime[idx]);
						if (ts.TotalSeconds >= waitSec)
						{
							if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
							{
								DIO.SetPortMotor(idx, eMotDir.CW, false, "상승전멈춤");
								System.Threading.Thread.Sleep(100);
							}

							DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(UP)");
							hmi1.arVar_Port[idx].AlignOK = 9; //올린다
															  //Pub.log.AddAT($"포트({idx}) 얼라인(UP) 작업 시작");
						}
					}
					else
					{
						//하강하는데 자재가 감지되고있네? - 하강상태가이면 하강한다
						if (DIO.GetIOOutput(DO_PORTRUN) == false)
						{
							if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
							{
								DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
								System.Threading.Thread.Sleep(100);
							}

							DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");
							PUB.log.Add("PORT", "Force port to descend");
						}

						//자재가 감지되면 시간을 다시 초기화해서 충분히 내려가도록 한다  210402
						PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;
					}

					//하단 리밋에 걸렷다면 반전시켜준다.  200708
					if (isPortLimDN(idx) == true)
					{
						if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
						{
							DIO.SetPortMotor(idx, eMotDir.CW, false, "리밋전환전멈춤");
							System.Threading.Thread.Sleep(100);
						}

						DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(LIM)");
						hmi1.arVar_Port[idx].AlignOK = 9;
						//Pub.log.AddAT($"포트({idx}) 얼라인(UP-LIM) 작업 시작");
					}
				}
				else if (PORTALIGN_OK == 9) //상승해서 찾는중
				{
					if (isPortDetUp(idx) || isPortLimUP(idx))
					{
						hmi1.arVar_Port[idx].AlignOK = 1; //정렬완료로처리
														  //Pub.log.AddAT($"포트({idx}) 얼라인 작업 완료");
					}
					else if (isPortDetUp(idx) == false || isPortLimUP(idx) == false)
					{
						//둘다 켜지 않은 상태에서 모터가 멈춰있다면 올려준다
						if (DIO.GetIOOutput(DO_PORTRUN) == false)
						{
							if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
							{
								DIO.SetPortMotor(idx, eMotDir.CW, false, "강제상승전멈춤");
								System.Threading.Thread.Sleep(100);
							}

							DIO.SetPortMotor(idx, eMotDir.CW, true, "MOT_PORT");
							PUB.log.Add("PORT", "Force ascend (stopped at position 9)");
						}
					}
				}
				else if (PORTALIGN_OK == 1)
				{
					//정렬완료로처리 - 201229
					hmi1.arVar_Port[idx].AlignOK = 1;
				}
				else
					hmi1.arVar_Port[idx].AlignOK = 0; //알수없는 상태이므로 처음부터 시작하게 한다
			}
			else
			{
				//여기코드는 PORT ALIGN 이 완료된상태(=1) 일 때 동작하는 코드이다
				if (PUB.flag.get(FG_RDY_PORT) == false)
				{
                    if(idx != 1)
                    {

                    }
					if (hmi1.arVar_Port[idx].errorCount > 5)
					{
						//5회이상 오류 발생햇으니 처리하지 않음
					}
					else if (isPortLimUP(idx) == true)
					{
						//상단 리밋이 확인됨(자재가 없는 경우임)
						if (idx != 1)
						{
							//언로더 포트는 리밋에 걸리더라도 사용해야한다(놓는것은 가능 함)
							//최초 상태에서는 반드시 이 상태가 된다
							PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
						}
						else
						{
							if (isPortDetUp(idx))
							{
								PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
							}
						}
					}
					else if (isPortDetUp(idx) == true)
					{
						//자재감지가 완료되었다?
						PUB.flag.set(FG_RDY_PORT, true, "RUN_MOT_P");
					}
					else
					{
						//모터를 올리는 작업을 진행해서 P-LIMIT를 찾아야 한다
						Boolean runMot = DIO.GetPortMotorDir(idx) == eMotDir.CCW;
						if (runMot == false)
						{
							if (DIO.GetIOOutput(DO_PORTRUN) == false) runMot = true;
						}
						if (runMot)
						{
							if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
							{
								DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#1)전멈춤");
								System.Threading.Thread.Sleep(100);
							}

							DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#1)");
						}
					}
				}
				else //포트가 준비되면 아무것도 안한다
				{
					//LIMIT이 들어와있는데 DETECT 센서도 들어와 있다면 다시 얼라인 잡게한다.
					if (DIO.GetIOInput(DI_LIMUP) == true)
					{
						//언로더포트 0,2번은 Ready 를 풀지 않는다.
						//그것은 P-LIM 상태라도 작업이 가능해야 한다
						if (idx == 1)
						{
							if (isPortDetUp(idx) == false)
								PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
						}
					}

					//자재가 감지되지 않았는데. LIMIT 가 아니라면 up을 시켜준다.
					if (DIO.GetIOInput(DI_DETUP) == false && DIO.GetIOInput(DI_LIMUP) == false)
					{
						//RDY를 해제 해준다
						PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");

						if (DIO.GetIOOutput(DO_PORTRUN) == false)
						{
							if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
							{
								DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#2)전멈춤");
								System.Threading.Thread.Sleep(100);
							}

							DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#2)");
						}
					}
				}
			}

			if (idx == 0)
				PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT0);
			else if (idx == 1)
				PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT1);
			else
				PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT2);

		}
	}
}
