using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using parkMonitor.DB;
using parkMonitor.LOG;
using parkMonitor.entity;
using parkMonitor.model;
using System.Configuration;
using System.Threading;
using parkMonitor.server.uiLogServer;
using parkMonitor.DBLocation;

namespace parkMonitor.server.CoreThread
{
    public abstract class AbstractCmd
    {
        public static bool isClosing { get; set; }
        public int equipmentStatus_address { set; get; }
        public int park_completed_address { set; get; }
        public int parkingEntX { set; get; }
        public int parkingEntY { set; get; }
        public int parkingEntZ { set; get; }
        public int fetch_completed_address { set; get; }
        public int wheelbase_status_address { get; set; }
        public IEquipments PLC { set; get; }
        public IEquipments queuingThread { set; get; }
        public DBOperation oper { set; get; }
        public IEquipments NumMachine { set; get; }
        public CEntrance cEntrance { set; get; }
        public AllotParkingSpace aps { set; get; }

        public int parking_startRobot_address { get; set; }
        public int fetching_startRobot_address { get; set; }
        public DBLocationOperator locationOper { get; set; }

        public int frontWheelbase_address { get; set; }
        public int rearWheelbase_address { get; set; }

        public Robot robot { get; set; }

        public AbstractCmd()
        {
            parking_startRobot_address = Convert.ToInt32(ConfigurationManager.AppSettings["parking_startRobot_address"]);
            fetching_startRobot_address = Convert.ToInt32(ConfigurationManager.AppSettings["fetching_startRobot_address"]);
            equipmentStatus_address = Convert.ToInt32(ConfigurationManager.AppSettings["equipmentStatus_address"]);
            park_completed_address = Convert.ToInt32(ConfigurationManager.AppSettings["park_completed_address"]);
            parkingEntX = Convert.ToInt32(ConfigurationManager.AppSettings["parkingEntX"]);
            parkingEntY = Convert.ToInt32(ConfigurationManager.AppSettings["parkingEntY"]);
            parkingEntZ = Convert.ToInt32(ConfigurationManager.AppSettings["parkingEntZ"]);
            //轮距
            frontWheelbase_address = Convert.ToInt32(ConfigurationManager.AppSettings["frontWheelbase_address"]);
            rearWheelbase_address = Convert.ToInt32(ConfigurationManager.AppSettings["rearWheelbase_address"]);
            wheelbase_status_address = Convert.ToInt32(ConfigurationManager.AppSettings["wheelbase_status_address"]);
            //取车完成
            fetch_completed_address = Convert.ToInt32(ConfigurationManager.AppSettings["fetch_completed_address"]);
            //获取PLC句柄
            PLC = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.PLC);
            //获取队列句柄
            queuingThread = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.Queue);
            //获取号牌机线程句柄
            NumMachine = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.NumMachine);
            //数据库
            oper = new DBOperation();
            //车位分配
            cEntrance = new CEntrance();
            aps = new AllotParkingSpace();
            robot = new Robot()
            {
                id = 1,
                parking_start_addr = parking_startRobot_address,
                fetching_start_addr = fetching_startRobot_address
            };
            locationOper = new DBLocationOperator();
        }
        public abstract void executeCmd(Command queueCmd);
        public void WaitForRobotResource(int robotID)
        {
            PLCMessage PLCMsg = null;
            lock (robot)
            {
                while (true)
                {
                    PLCMsg = (PLCMessage)PLC.GetMessage();
                    bool occupied = false;
                    if (PLCMsg != null)
                    {
                        if (robotID == 1)
                        {
                            try
                            {
                                robot.parking_start_value = Convert.ToInt32(PLCMsg.originalPlcList[parking_startRobot_address].Value);
                                robot.fetching_start_value = Convert.ToInt32(PLCMsg.originalPlcList[fetching_startRobot_address].Value);
                                //刷新机械手资源状态值
                                if (robot.parking_start_value == 0 && robot.fetching_start_value == 0 && !robot.occupied)
                                {
                                    occupied = false;
                                }
                                else
                                {
                                    occupied = true;
                                }
                            }
                            catch { }
                        }
                    }
                    if (occupied)
                    {
                        Thread.Sleep(3000);
                    }
                    else
                    {
                        robot.occupied = true;
                        break;
                    }
                }
            }
        }
    }

    public class StopCmd : AbstractCmd
    {
        /// <summary>
        /// 命令中号牌与对应号牌机中当前号牌比对，确认车辆
        /// </summary>
        private bool NumValidation(Command queueCmd, int countdown, float ratio)
        {
            List<NumberMachineNode> numList = ((NumberMachineMessage)NumMachine.GetMessage()).data;
            bool result = false;
            Task numberCheck = Task.Factory.StartNew(() =>
            {
                int myCountdown = countdown, count = 0;
                while (myCountdown-- > 0)
                {
                    foreach (NumberMachineNode node in numList)
                    {
                        if (queueCmd.ip.Equals(node.ip) && queueCmd.LicenseNum.Equals(node.LicenseNum))
                        {
                            count += 1;
                        }
                    }
                    Thread.Sleep(500);
                }
                if (count >= (int)(countdown * ratio))
                {
                    result = true;
                }
                else
                {
                    result = false;
                }
            });
            numberCheck.Wait();
            return result;
        }

        /// <summary>
        /// 号牌复位
        /// </summary>
        private void NumReset(Command queueCmd)
        {
            NumberMachineMessage numberMachineMessage = new NumberMachineMessage();
            numberMachineMessage.aNode = new NumberMachineNode();
            numberMachineMessage.aNode.ip = "";
            numberMachineMessage.aNode.LicenseNum = queueCmd.LicenseNum;
            queuingThread.SetMessage(numberMachineMessage);
        }
        /// <summary>
        /// 车位资源
        /// </summary>
        /// <param name="queueCmd"></param>
        /// <returns></returns>
        private Parking_Space WaitForParkingSpaceResource(Command queueCmd)
        {
            //中心点
            cEntrance.parkingEntX = parkingEntX;
            cEntrance.parkingEntY = parkingEntY;
            cEntrance.parkingEntZ = parkingEntZ;
            Parking_Space ppp = new Parking_Space();
            while (true)
            {
                if (!queueCmd.manual)
                {
                    ppp = aps.MallocParkingSpace(cEntrance, oper, queueCmd);//自动
                }
                else
                {
                    ppp = aps.MallocParkingSpace(cEntrance, locationOper, queueCmd);//手动
                }
                if (ppp != null)
                {
                    break;
                }
                if (isClosing)
                {
                    break;
                }
                Thread.Sleep(200);
            }
            return ppp;
        }
        private Data WaitForLaserResource(Command queueCmd, bool disappeared)
        {
            //激光数据
            Data data = new Data();
            bool jumpOut = false;
            PLCMessage PLCMsg = null;
            jumpOut = false;
            while (true)
            {
                PLCMsg = (PLCMessage)PLC.GetMessage();
                if (PLCMsg != null)
                {
                    foreach (LaserMessage lm in PLCMsg.laserMsgList)
                    {
                        if (lm.id == queueCmd.id && lm.data != null)
                        {
                            lock (lm)
                            {
                                //判断车辆检测结果,
                                if (disappeared)
                                {
                                    lm.abort_rescan = true;
                                    jumpOut = true;
                                    break;
                                }
                                //存储相应激光数据
                                if (lm.recorded)
                                {
                                    data.angleA = lm.data.angleA;
                                    data.centerX = lm.data.centerX;
                                    data.centerY = lm.data.centerY;
                                    data.length = lm.data.length;
                                    data.width = lm.data.width;
                                    data.height = lm.data.height;
                                    jumpOut = true;
                                    lm.recorded = false;
                                    break;
                                }
                                else if (lm.status == -1)
                                {
                                    LogFile logFile = LogFile.ERROR;
                                    UILogServer.ins.error("激光" + lm.id + "连接异常");
                                    Log.WriteLog(logFile, "激光异常");
                                    Thread.Sleep(5000);
                                }
                            }
                        }
                    }
                    if (jumpOut)
                    {
                        break;
                    }
                }
                Thread.Sleep(1000);
            }
            return data;
        }
        /// <summary>
        /// 停车完成
        /// </summary>
        private void WaitForStoreSignal(Command queueCmd, ref int parkingSpaceID, ref bool robotError, int status)
        {
            PLCMessage PLCMsg = null;
            while (true)
            {
                Thread.Sleep(1000);
                PLCMsg = (PLCMessage)PLC.GetMessage();
                int storeStatus = Convert.ToInt32(PLCMsg.originalPlcList[park_completed_address].Value);
                //停车完成信号
                if (storeStatus == status)
                {
                    break;
                }
                else if (1 == 2)//机械手异常，则退指令，写数据库归位
                {
                    robotError = true;
                    queueCmd.returnedCount += 1;
                    queuingThread.SetMessage(queueCmd);
                    if (!queueCmd.manual)
                    {
                        oper.UpdateParkingSpaceState(parkingSpaceID, 0);
                    }
                    else
                    {
                        locationOper.UpdateParkingSpaceState(parkingSpaceID, 0);
                    }
                    break;
                }
            }
        }
        private void WaitWheelbase(ref int frontWheelbase, ref int rearWheelbase)
        {
            PLCMessage PLCMsg = null;
            while (!isClosing)
            {
                PLCMsg = (PLCMessage)PLC.GetMessage();
                int wheelbaseStatus = Convert.ToInt32(PLCMsg.originalPlcList[wheelbase_status_address].Value);
                //停车完成信号
                if (wheelbaseStatus == 3)
                {
                    frontWheelbase = Convert.ToInt32(PLCMsg.originalPlcList[frontWheelbase_address].Value);
                    rearWheelbase = Convert.ToInt32(PLCMsg.originalPlcList[rearWheelbase_address].Value);
                    break;
                }
                Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 停车流程
        /// </summary>
        /// <param name="queueCmd"></param>
        public override void executeCmd(Command queueCmd)
        {
            //第一步：
            int status = 1;//停车
            ControlMessage cm = new ControlMessage();
            cm.status = status;
            cm.laserID = queueCmd.id;//启动对应激光
            PLC.SetMessage(cm);
            Console.WriteLine("停车，开激光:" + queueCmd.LicenseNum);
            Log.WriteLog("停车，开激光:" + queueCmd.LicenseNum);
            UILogServer.ins.info("停车，开激光:" + queueCmd.LicenseNum);

            Parking_Space ppp = new Parking_Space();
            Task parkingSpace = Task.Factory.StartNew(() =>
            {
                ppp = WaitForParkingSpaceResource(queueCmd);
            });
            //int garageID = ppp.garageID;
            string numberPlate = queueCmd.LicenseNum;
            int userID = 0;
            //过期号牌判断
            if (queueCmd.userID != "")
            {
                userID = Convert.ToInt32(queueCmd.userID);
            }
            int garageID = queueCmd.garageID;
            string realParkTime = queueCmd.TimeRecord;
            bool disappeared = false;
            bool stopChecking = false;
            bool robotError = false;
            //Task checkNum = Task.Factory.StartNew(() =>
            //{
            //    DateTime startTime = DateTime.Now;
            //    DateTime endTime = DateTime.Now;
            //    TimeSpan t = startTime - endTime;
            //    while (!stopChecking && t.TotalSeconds <= 600)
            //    {
            //        //号牌验证,异常则退回队列
            //        Func<Command, int, float, bool> numValidationResult = new Func<Command, int, float, bool>(NumValidation);
            //        IAsyncResult result = numValidationResult.BeginInvoke(queueCmd, 10, 0.7f, null, null);
            //        bool checkResult = numValidationResult.EndInvoke(result);
            //        if (stopChecking)
            //        {
            //            return;
            //        }
            //        if (!checkResult)
            //        {
            //            UILogServer.ins.info("停车命令" + queueCmd.LicenseNum + " 与当前车辆不一致");
            //            disappeared = true;
            //            return;
            //            //未能停车，将车辆状态复位
            //            //oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
            //        }
            //        endTime = DateTime.Now;
            //        t = startTime - endTime;
            //    }
            //});
            Data dataReal = new Data();
            Task dataFromLaser = Task.Factory.StartNew(() =>
            {
                dataReal = WaitForLaserResource(queueCmd, disappeared);
            });
            Task.WaitAll(parkingSpace, dataFromLaser);
            //车位
            int parkingSpaceID = ppp.parkingSpaceID;
            int parkingSpaceX = ppp.parkingSpaceX;
            int parkingSpaceY = ppp.parkingSpaceY;
            int parkingSpaceZ = ppp.parkingSpaceZ;
            //激光数据
            int centerX = dataReal.centerX;
            int centerY = dataReal.centerY;
            int angleA = dataReal.angleA;
            int length = dataReal.length;
            int width = dataReal.width;
            int height = dataReal.height;
            //号牌失效，数据库回滚
            if (disappeared)
            {
                NumReset(queueCmd);
                if (!queueCmd.manual)
                {
                    oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                }
                else
                {
                    locationOper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                }
                return;
            }
            stopChecking = true;//开始启动机械手，停止检测号牌
            UILogServer.ins.log("停止核对，准备启动机械手");
            int robotID = 0;
            robotID = queueCmd.id / 3 + 1;

            int frontWheelbase = 0;
            int rearWheelbase = 0;
            Task robotFree = Task.Factory.StartNew(() =>
            {
                //需要先遍历robot数组，根据id找到对应机械手
                WaitForRobotResource(robotID);
            });
            robotFree.Wait();
            //第二步：
            status = 2;
            cm.status = status;
            cm.RobotID = robotID;//启动对应机械手
            cm.centerX = Convert.ToString(centerX);
            cm.centerY = Convert.ToString(centerY);
            cm.angleA = Convert.ToString(angleA);
            cm.length = Convert.ToString(length);
            cm.width = Convert.ToString(width);
            cm.height = Convert.ToString(height);
            cm.parkingSpaceID = Convert.ToString(parkingSpaceID);
            cm.parkingSpaceX = Convert.ToString(parkingSpaceX);
            cm.parkingSpaceY = Convert.ToString(parkingSpaceY);
            cm.parkingSpaceZ = Convert.ToString(parkingSpaceZ);
            PLC.SetMessage(cm);

            Console.WriteLine("停车，抓车:" + queueCmd.LicenseNum);
            Log.WriteLog("停车，抓车:" + queueCmd.LicenseNum);
            UILogServer.ins.info("停车，抓车:" + queueCmd.LicenseNum);

            Task dataFromWheelbase = Task.Factory.StartNew(() =>
            {
                WaitWheelbase(ref frontWheelbase, ref rearWheelbase);
            });

            Task storeSignal = Task.Factory.StartNew(() =>
            {
                WaitForStoreSignal(queueCmd, ref parkingSpaceID, ref robotError, 1);
            });
            //storeSignal.Wait();
            Task.WaitAll(dataFromWheelbase, storeSignal);
            //第三步：
            status = 3;
            cm.status = status;
            PLC.SetMessage(cm);
            Task storeResetSignal = Task.Factory.StartNew(() =>
            {
                WaitForStoreSignal(queueCmd, ref parkingSpaceID, ref robotError, 0);
            });
            storeResetSignal.Wait();
            robot.occupied = false;
            //机械手异常则跳出
            if (robotError)
            {
                PLC.SetMessage(new PLCNode(parking_startRobot_address.ToString(), "0"));
                //把号牌丢回
                queueCmd.returnedCount += 1;
                PLC.SetMessage(queueCmd);
                return;
            }
            //停车流程结束，将相应车牌复位
            NumReset(queueCmd);
            //if (disappeared)
            //{
            //    PLC.SetMessage(new PLCNode(parking_startRobot_address.ToString(), "0"));
            //    oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
            //    UILogServer.ins.info("抓车失败，状态复位");
            //    return;
            //}
            Console.WriteLine("停车完成，状态复位");
            Log.WriteLog("停车完成，状态复位");
            UILogServer.ins.info("停车完成，状态复位");
            //根据号牌查找车型
            //int vehicleTypeID = oper.getVehicleTypeID(numberPlate);
            //判断测量数据是否准确
            //bool isDataRight = oper.IsDataRight(vehicleTypeLength, vehicleTypeWidth, vehicleTypeHeight, vehicleTypeWheelbase, vehicleTypeID);

            //正常写入数据库
            if (userID != 0)
            {
                if (queueCmd.manual == false)
                {
                    //更新云端数据库
                    //插入停车记录表
                    int parkingRecordsID = oper.InsertToParkingRecords(userID, numberPlate, parkingSpaceID, garageID, 3, realParkTime);
                    //车辆表更新车辆信息
                    oper.UpdateVehicle(numberPlate, 1, realParkTime, parkingRecordsID, parkingSpaceID, 1, frontWheelbase, rearWheelbase);
                    //更新车库表剩余车位数
                    int freeSpaceCount = oper.getGarageFreeSpace(garageID);
                    freeSpaceCount = freeSpaceCount - 1;
                    oper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                    //更新车位表车位状态
                    oper.UpdateParkingSpaceState(parkingSpaceID, 1);
                    //插入消息队列表
                    oper.InsertToMessageQueue(userID, "停车成功", 1);

                    ////更新本地数据库
                    //int parkingRecordsIDLocation = locationOper.InsertToParkingRecords(0, userID, numberPlate, parkingSpaceID, garageID, 3, realParkTime);
                    ////车辆表更新车辆信息
                    //locationOper.UpdateVehicle(numberPlate, 1, parkingRecordsIDLocation, parkingSpaceID, 1);
                    ////更新车库表剩余车位数
                    //locationOper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                    ////更新车位表车位状态
                    //locationOper.UpdateParkingSpaceState(parkingSpaceID, 1);
                }
                else
                {
                    //插入停车记录表
                    int parkingRecordsID = locationOper.InsertToParkingRecords(1, userID, numberPlate, parkingSpaceID, garageID, 3, realParkTime, frontWheelbase, rearWheelbase);
                    ////判断车辆表是否存在车辆
                    //bool isNumberPlateFromVehicle = locationOper.IsNumberPlateFromVehicle(numberPlate);
                    //if (isNumberPlateFromVehicle == false)
                    //{
                    //    //车辆表更新车辆信息
                    //    locationOper.InsertVehicle(numberPlate, 1, parkingRecordsID, parkingSpaceID, 1);
                    //}
                    //else
                    //{
                    //    locationOper.UpdateVehicle(numberPlate, 1, parkingRecordsID, parkingSpaceID, 1);
                    //}
                    //更新车库表剩余车位数
                    int freeSpaceCount = locationOper.getGarageFreeSpace(garageID);
                    freeSpaceCount = freeSpaceCount - 1;
                    locationOper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                    //更新车位表车位状态
                    locationOper.UpdateParkingSpaceState(parkingSpaceID, 1);
                }
            }
            //异常写入日志文件
            else
            {
                LogFile logFile = LogFile.ERROR_NUMBERPLATE;
                Log.WriteLog(logFile, "号牌：" + numberPlate);
                Log.WriteLog(logFile, "入库时间：" + realParkTime);
                Log.WriteLog(logFile, "车位id：" + parkingSpaceID);
                Log.WriteLog(logFile, "车位x：" + parkingSpaceX);
                Log.WriteLog(logFile, "车位y：" + parkingSpaceY);
                Log.WriteLog(logFile, "车位z：" + parkingSpaceZ);
                //异常情况处理有待讨论
            }
        }
    }

    public class FetchCmd : AbstractCmd
    {
        public override void executeCmd(Command queueCmd)
        {
            PLCMessage PLCMsg = null;
            Vehicle vehiclelist = null;
            if (queueCmd.manual)
            {
                vehiclelist = locationOper.GetVehicle(queueCmd.LicenseNum, queueCmd.garageID);
            }
            else
            {
                vehiclelist = oper.GetVehicle(queueCmd.LicenseNum);
            }
            int parkingSpaceID = vehiclelist.parkingSpaceID;
            int garageID = vehiclelist.garageID;
            int frontwheelbase = vehiclelist.frontwheelbase;
            int rearwheelbase = vehiclelist.rearwheelbase;
            Fetching_Space fslist = null;
            if (queueCmd.manual)
            {
                fslist = locationOper.GetFetchingSpace(parkingSpaceID);
            }
            else
            {
                fslist = oper.GetFetchingSpace(parkingSpaceID);
            }
            int parkingSpaceX = fslist.parkingSpaceX;
            int parkingSpaceY = fslist.parkingSpaceY;
            int parkingSpaceZ = fslist.parkingSpaceZ;
            ControlMessage cm = new ControlMessage();

            int robotID = 0;
            robotID = parkingSpaceID / 15 + 1;
            Task robotFree = Task.Factory.StartNew(() =>
            {
                WaitForRobotResource(robotID);
            });
            robotFree.Wait();
            //取车
            int status = 4;
            cm.status = status;
            //先手动赋值
            cm.RobotID = 1;
            cm.fetchPosition = 1;//放置地址
            cm.parkingSpaceID = Convert.ToString(parkingSpaceID);
            cm.parkingSpaceX = Convert.ToString(parkingSpaceX);
            cm.parkingSpaceY = Convert.ToString(parkingSpaceY);
            cm.parkingSpaceZ = Convert.ToString(parkingSpaceZ);
            cm.frontWheelbase = frontwheelbase;
            cm.rearWheelbase = rearwheelbase;
            PLC.SetMessage(cm);

            Console.WriteLine("取车:" + queueCmd.LicenseNum);
            Log.WriteLog("取车:" + queueCmd.LicenseNum);
            UILogServer.ins.info("取车:" + queueCmd.LicenseNum);
            //等待PLC取车完成信号
            Task signalFromPLC = Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Thread.Sleep(2000);
                    PLCMsg = (PLCMessage)PLC.GetMessage();
                    int fetchingStatus = Convert.ToInt32(PLCMsg.originalPlcList[fetch_completed_address].Value);
                    //取车完成信号
                    if (fetchingStatus == 1)
                    {
                        //取车完成后或可归零
                        break;
                    }
                }
            });
            //Task.WaitAll(signalFromPLC);
            signalFromPLC.Wait();
            //取车完成
            status = 5;
            ControlMessage cm2 = new ControlMessage();
            cm2.status = status;
            //先手动赋值
            cm2.RobotID = 1;
            PLC.SetMessage(cm2);
            Task signalResetFromPLC = Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Thread.Sleep(2000);
                    PLCMsg = (PLCMessage)PLC.GetMessage();
                    int fetchingStatus = Convert.ToInt32(PLCMsg.originalPlcList[fetch_completed_address].Value);
                    //取车完成复位信号
                    if (fetchingStatus == 0)
                    {
                        //取车完成后或可归零
                        break;
                    }
                }
            });
            //Task.WaitAll(signalFromPLC);
            signalResetFromPLC.Wait();
            robot.occupied = false;
            Console.WriteLine("号牌：" + queueCmd.LicenseNum + "取车完成");
            Log.WriteLog("号牌：" + queueCmd.LicenseNum + "取车完成");
            UILogServer.ins.info("号牌：" + queueCmd.LicenseNum + "取车完成");
            //数据库更新
            if (queueCmd.manual == false)
            {
                //云端数据库更新
                //更新车库表车位数
                int freeSpaceCount = oper.getGarageFreeSpace(garageID);
                freeSpaceCount = freeSpaceCount + 1;
                oper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                //更新车位表车位状态
                oper.UpdateParkingSpaceState(parkingSpaceID, 0);
                //更新车辆表车辆停车状态
                oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                //更新停车记录表
                oper.UpdateParkingRecords(6, queueCmd.TimeRecord, queueCmd.parkingRecordsID);

                ////本地数据库更新
                //locationOper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                ////更新车位表车位状态
                //locationOper.UpdateParkingSpaceState(parkingSpaceID, 0);
                ////更新车辆表车辆停车状态
                //locationOper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                ////更新停车记录表
                //locationOper.UpdateParkingRecords(0, 6, queueCmd.TimeRecord, queueCmd.parkingRecordsID);
            }
            else
            {
                //更新车库表车位数
                int freeSpaceCount = locationOper.getGarageFreeSpace(garageID);
                freeSpaceCount = freeSpaceCount + 1;
                locationOper.UpdateGarageFreeSpace(freeSpaceCount, garageID);
                //更新车位表车位状态
                locationOper.UpdateParkingSpaceState(parkingSpaceID, 0);
                ////更新车辆表车辆停车状态
                //locationOper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                //更新停车记录表
                locationOper.UpdateParkingRecords(0, 6, queueCmd.TimeRecord, queueCmd.parkingRecordsID);
            }
        }
    }

    public class ExceptionCmd : AbstractCmd
    {
        public override void executeCmd(Command queueCmd)
        {
            if (queueCmd.commandType == 'e')
            {
                int userId = Convert.ToInt32(queueCmd.userID);
                //过期用户指令
                oper.InsertToMessageQueue(userId, "停车异常，请联系管理员！", 2);
                //未能停车，将车辆状态复位
                oper.UpdateVehicleParkState(queueCmd.LicenseNum, 0);
                LogFile logFile = LogFile.ERROR_NUMBERPLATE;
                Log.WriteLog(logFile, "过期用户指令,车牌号：" + queueCmd.LicenseNum);
                UILogServer.ins.error("过期用户指令,车牌号：" + queueCmd.LicenseNum);
                //continue;
            }
        }
    }

    public class SimpleCMDFactory
    {
        public AbstractCmd createCmd(Command queueCmd)
        {
            AbstractCmd abstractCmd = null;

            if (queueCmd.commandType == 's')
            {
                abstractCmd = new StopCmd();
            }
            if (queueCmd.commandType == 'f')
            {
                abstractCmd = new FetchCmd();
            }
            if (queueCmd.commandType == 'e')
            {
                abstractCmd = new ExceptionCmd();
            }
            return abstractCmd;
        }
    }

}
