using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Common;
using Domain;
using RCUHost.Protocols;
using CommonEntity;

namespace RCUHost.Implement
{
    public class DeviceControlReceiver : GenericReceiverBase, IDeviceControlReceiver
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(DeviceControlReceiver));

        public void Send(Host host, Device device)
        {
            Send(host, new List<Device> { device });
        }

        public void Send(Host host, IList<Device> devices)
        {
            var data = CreateDeviceControlPacket(devices);
            SendAndPushCommandQueue(data, host.HostNumber, host.MAC);// host.IP, host.Port);

            //需要在这里添加代码
            //StringBuilder builder = new StringBuilder();
            //for (int i = 0; i < data.Length; i++)
            //{
            //    builder.Append(string.Format("{0:X2} ", data[i]));
            //}
            //string nnn = builder.ToString().Trim();
            //logger.Error(string.Format("给酒店({0})客房({1})发送控制命令{2}", host.SysHotel.Code, host.RoomNumber,builder.ToString()));
        }
        public void Send_Repeat(string Key,Host host, Device device)
        {
            Send_Repeat(Key,host, new List<Device> { device });
        }
        public void Send_Repeat(string PrefixKey, Host host, IList<Device> devices)
        {
            try
            {
                StringBuilder sb = new StringBuilder();

                sb.Append(CacheKey.SendDataRepeatKey);
                sb.Append("_");
                sb.Append(PrefixKey);
                string SingleKey = sb.ToString();

                var data = CreateDeviceControlPacket(devices);

                //AA 55 11 00 54 33 53 41 0F 
                //80 2E 2C 08 0E BD 
                //8F CF 
                byte[] store_xuhao = null;
                var obj = MemoryCacheHelper.Get(SingleKey);
                if (obj != null)
                {
                    store_xuhao = (byte[])obj;
                    data[9] = store_xuhao[0];
                    data[10] = store_xuhao[1];
                }
                else
                {
                    var xuhao = data.Skip(9).Take(2);
                    MemoryCacheHelper.Set(SingleKey, xuhao.ToArray());
                }

                SendAndPushCommandQueue(data, host.HostNumber, host.MAC);// host.IP, host.Port);
            }
            catch (Exception)
            {

            }
            //需要在这里添加代码
            //StringBuilder builder = new StringBuilder();
            //for (int i = 0; i < data.Length; i++)
            //{
            //    builder.Append(string.Format("{0:X2} ", data[i]));
            //}
            //string nnn = builder.ToString().Trim();
            //logger.Error(string.Format("给酒店({0})客房({1})发送控制命令{2}", host.SysHotel.Code, host.RoomNumber,builder.ToString()));
        }


        public override void Process(ReceiverContext context)
        {
        }

        public byte[] CreateDeviceControlPacket(IList<Device> devices)
        {
            SystemHeader systemHeader = CreateSystemHeader();
            byte[] deviceControlDataPacket = CreateDeviceControlDataPacket(devices);
            int size = StructConverter.SizeOf(systemHeader) + deviceControlDataPacket.Length + 2;

            systemHeader.FrameLength = (ushort)size;

            using (MemoryStream stream = new MemoryStream(size))
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    writer.Write(StructConverter.StructToBytes(systemHeader));
                    writer.Write(deviceControlDataPacket);
                    writer.Write(new byte[] { 0, 0 });
                    return stream.ToArray();
                }
            }
        }

        public byte[] CreateDeviceControlDataPacket(IList<Device> devices)
        {
            using (MemoryStream buffer = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(buffer))
                {
                    writer.Write((byte)devices.Count);//数量
                    foreach (var device in devices)
                    {
                        switch (device.AddressType)
                        {
                            case AddressType.DeviceAddress:
                                //根据新的A6主机调整 Modified By Jophy Wu on 20180704 
                                //先把继电器、扩展板、调光、可控硅和灯带加上去，其他几个设备可以走之前的协议
                                writer.Write(DeviceAddress.Parse(device.Address).GetBytes());//地址
                                //判断设备类型，对应输出类型（方式1字节+内容1字节）
                                switch (device.Type)
                                {
                                    case DeviceType.Relay://主机继电器
                                    case DeviceType.Expand://扩展继电器
                                    case DeviceType.ServiceInfo://服务信息
                                    case DeviceType.Curtain://窗帘
                                    case DeviceType.WXLock://微信锁
                                    case DeviceType.SwitchExpand://开关扩展
                                    case DeviceType.A9IORelay://A9IO继电器
                                    case DeviceType.CardPower://插卡取电
                                    case DeviceType.InFrared://红外感应
                                    case DeviceType.PB20_RELAY:
                                        writer.Write(device.Status);//1开，2关
                                        writer.Write((byte)0);
                                        break;
                                    case DeviceType.Dimmer://LED调光
                                    case DeviceType.Traic://可控硅调光
                                    case DeviceType.Strip://灯带调光
                                    case DeviceType.PWMDimmer://PWM调光
                                    case DeviceType.PWMExpand://PWM扩展
                                    case DeviceType.PBLED://PB LED
                                    case DeviceType.LVout://弱电输出
                                    case DeviceType.PB20:
                                    case DeviceType.PB20_LD:
                                    case DeviceType.PB20_LS:
                                        writer.Write(device.Status);
                                        writer.Write(device.Brightness);
                                        break;
                                    case DeviceType.AirConditioner://空调
                                        byte[] airExecMode = Tools.Int32ToByte2(device.AirExecMode);
                                        foreach (byte b in airExecMode)
                                        {
                                            writer.Write(b);
                                        }
                                        break;
                                    case DeviceType.FloorHot://地暖
                                        byte[] floorHotExecMode = Tools.Int32ToByte2(device.FloorHotExecMode);
                                        foreach (byte b in floorHotExecMode)
                                        {
                                            writer.Write(b);
                                        }
                                        break;
                                    case DeviceType.Music://音乐
                                        byte[] musicExecMode = Tools.Int32ToByte2(device.MusicExecMode);
                                        foreach (byte b in musicExecMode)
                                        {
                                            writer.Write(b);
                                        }
                                        break;
                                    case DeviceType.TV://电视
                                        writer.Write(device.Status);//1开，2关，3匹配，4频道。
                                        switch (device.Status)
                                        {
                                            case 0x03://status==3时：1空调，2电视
                                                break;
                                            case 0x04://status==4时：1~255频道
                                                writer.Write(device.Valve);
                                                break;
                                            default://功能：1~15，只是开关时，内容是0
                                                writer.Write(device.Mode);
                                                break;
                                        }
                                        break;
                                    case DeviceType.ColorTemp://色溫
                                        writer.Write(device.Status);
                                        switch (device.Status)
                                        {
                                            case 3:
                                                writer.Write(device.Temperature);//0~100
                                                break;
                                            default:
                                                writer.Write(device.Brightness);
                                                break;
                                        }
                                        break;
                                    default:
                                        //其他走以前的协议
                                        writer.Write((byte)device.AddressType);//地址类型
                                        writer.Write(device.Status);//状态
                                        break;
                                }
                                break;
                            case AddressType.GroupAddress://指令场景
                                writer.Write((byte)0);//设备类型1字节
                                writer.Write(GroupAddress.Parse(device.Address).GetBytes());//地址
                                writer.Write(device.Status);//1开，2关
                                writer.Write((byte)0);
                                break;
                        }
                    }
                    return buffer.ToArray();
                }
            }
        }

        public override CommandType CommandType
        {
            get { return CommandType.DeviceControl; }
        }
    }
}
