using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;

namespace Project
{
	public partial class FMain
	{
		DateTime lastDeleteTime = DateTime.Now;
		DateTime HomeSuccessTime;
		DateTime HomeChkTime;
	

		void SM_Loop(object sender, StateMachine.RunningEventArgs e)
		{
			//main loop
			var step = (eSMStep)e.Step;
			var obj = this.GetType();

			var stepName = step.ToString();
			var methodName = $"_STEP_{stepName}";
			var methodNameStart = $"_STEP_{stepName}_START";
			var runMethodName = $"_{stepName}";

			var method = obj.GetMethod(methodName);
			var methodS = obj.GetMethod(methodNameStart);

			switch (step)
			{
				case eSMStep.NOTSET:
					PUB.log.Add("S/M Initialize Start");
					PUB.sm.SetNewStep(eSMStep.INIT);
					break;

				case eSMStep.WAITSTART:
					if (e.isFirst) PUB.log.Add("EVENT WAITSTART");
					break;

				case eSMStep.PAUSE:
				case eSMStep.EMERGENCY:
				case eSMStep.ERROR:
					if (e.isFirst)
						_SM_MAIN_ERROR(e.isFirst, (eSMStep)e.Step, e.StepTime);
					break;

				default:

					if (e.isFirst)
					{
						//시작명령은 반드시 구현할 필요가 없다
						if (methodS != null) methodS.Invoke(this, new object[] { step });
						else
						{
							hmi1.ClearMessage();
							PUB.log.Add($"Undefined STEP({step}) started");
						}

						if (step == eSMStep.HOME_QUICK || step == eSMStep.HOME_FULL || PUB.sm.getOldStep == eSMStep.IDLE || PUB.sm.getOldStep == eSMStep.FINISH)
						{
							PUB.sm.seq.ClearData(step);
							PUB.sm.seq.Clear(step);
						}

						PUB.sm.seq.ClearTime();
						PUB.sm.RaiseStepStarted();
					}

					if (PUB.popup.needClose) System.Threading.Thread.Sleep(10);
					else
					{
						//스텝번호값 보정 220313
						if (PUB.sm.seq.Get(step) < 1) PUB.sm.seq.Update(step, 1);

						if (method == null)
						{
							var runMethod = obj.GetMethod(runMethodName);
							if (runMethod == null)
							{
								PUB.log.AddE($"The following command is not implemented {methodName}/{runMethodName}");
								PUB.Result.SetResultMessage(eResult.DEVELOP, eECode.NOFUNCTION, eNextStep.ERROR, methodName, runMethodName);
							}
							else
							{
								var stepName2 = step.ToString();

								//실행코드는 있으니 처리한다.
								if (PUB.popup.needClose) System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
								else
								{
									//실행가능여부를 확인 합니다
									if (CheckSystemRunCondition() == true)
									{
										//동작상태가 아니라면 처리하지 않는다.
										if (PUB.sm.Step == step && PUB.sm.getNewStep == step)
										{
											var param = new object[] { step };
											var rlt = (bool)runMethod.Invoke(this, param);
											if (rlt == true)
											{
												PUB.log.AddI("User step(automatic) execution completed, switching to idle state");
												PUB.sm.SetNewStep(eSMStep.IDLE, true);
											}
										}
									}
								}
							}
						}
						else
						{
							var param = new object[] { step, e.StepTime, PUB.sm.seq.GetTime(step) };
							var rlt = (StepResult)method.Invoke(this, param);
							if (rlt == StepResult.Complete) PUB.sm.RaiseStepCompleted();
							else
							{
								//사용자 스텝이 설정되어있다면 자동으로 멈춘다  220223
								if (rlt == StepResult.Error)
								{
									if (PUB.sm.getNewStep != eSMStep.ERROR)
										PUB.sm.SetNewStep(eSMStep.ERROR);
								}

								if (PUB.flag.get(eVarBool.FG_USERSTEP) == true)
								{
									if (PUB.sm.Step >= eSMStep.RUN && PUB.sm.getNewStep >= eSMStep.RUN &&
										PUB.sm.Step < eSMStep.FINISH && PUB.sm.getNewStep < eSMStep.FINISH)
									{
										//유저스텝에 걸려있지 않다면 자동으로 멈춘다
										if (LockUserL.WaitOne(10) && LockUserR.WaitOne(10))
										{
											//Pub.Result.SetResultMessage(eResult.OPERATION, eECode.USER_STOP)
											PUB.Result.ResultMessage = string.Empty;
											PUB.sm.SetNewStep(eSMStep.PAUSE);
										}
									}
								}
							}
						}
					}
					break;
			}
		}

		void DeleteFile(string path)
		{
			var basetime = DateTime.Now.AddDays(-1 * AR.SETTING.Data.AutoDeleteDay);
			var di = new System.IO.DirectoryInfo(path);
			if (di.Exists)
			{
				var dirYear = di.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
				if (dirYear != null)
				{
					var dirMon = dirYear.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
					if (dirMon != null)
					{
						var dirDay = dirMon.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
						if (dirDay != null)
						{
							var curDay = DateTime.Parse(string.Format("{0}-{1}-{2} 00:00:00", dirYear.ToString(), dirMon.ToString(), dirDay.ToString()));
							if (curDay < basetime)
							{
								var dirLot = dirDay.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
								if (dirLot != null)
								{
									var delfile = dirLot.GetFiles().FirstOrDefault();
									if (delfile != null)
									{
										try
										{
											PUB.log.AddI("Remove Fle : " + delfile.FullName + ",time=" + delfile.LastWriteTime.ToString());
											delfile.Delete();
										}
										catch (Exception ex)
										{
											PUB.log.AddE("deleete error : " + ex.Message);
										}
									}
									else
									{
										string delpath = dirLot.FullName;
										try
										{
											dirLot.Delete(true);
										}
										catch (Exception ex)
										{
											PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
										}

									}
								}
								else
								{
									//이 폴더아래에 다른 폴더가 하나도 없다 즉 비어 있따.
									string delpath = dirDay.FullName;
									try
									{
										dirDay.Delete(true);
									}
									catch (Exception ex)
									{
										PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
									}
								}
							}

						}
						else
						{
							//날짜에 해당하는 폴더가 하나도 없다. 월 폴더를 제거한다.
							string delpath = dirMon.FullName;
							try
							{
								dirMon.Delete(true);
							}
							catch (Exception ex)
							{
								PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
							}
						}
					}
					else
					{
						//이 달에 해당하는 데이터가 없다. 이 년도를 삭제한다.
						string delpath = dirYear.FullName;
						try
						{
							dirYear.Delete(true);
						}
						catch (Exception ex)
						{
							PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
						}
					}
				}
				//년도별폴더목록을 정리함
				//가장작은 년도를 기준으로 파일을 검색해서 1개씩 삭제함
			}
		}


	}
}
