using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace RCUHost.Protocols
{
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct GroupAddress
	{
		[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)]
		public readonly byte[] groupAddress;

		public GroupAddress(byte[] groupAddress)
		{
			if (groupAddress != null && groupAddress.Length == 3)
			{
				this.groupAddress = groupAddress;
			}
			else
			{
				throw new ApplicationException("无效的组地址。");
			}
		}

		/// <summary>
		/// 创建一个组地址
		/// </summary>
		/// <param name="groupAddress">字符串格式的组地址，如：1.2.3</param>
		public GroupAddress(string groupAddress)
		{
			this.groupAddress = Parse(groupAddress).GetBytes();
		}

		/// <summary>
		/// 获取组地址的字节表示
		/// </summary>
		/// <returns></returns>
		public byte[] GetBytes()
		{
			return this.groupAddress;
		}

		public override string ToString()
		{
			return String.Join(".", groupAddress);
		}

		public static GroupAddress Parse(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				throw new ArgumentNullException("s");
			}

			byte[] arrGroupAddr = new byte[3] { 0, 0, 0 };

			try
			{
				if (s.Count(r => r == '.') != 2)
				{
					throw new ApplicationException("组地址必须是以三段点分十进制组成。");
				}

				arrGroupAddr = s.Split('.').Select(r => Convert.ToByte(r)).ToArray();
			}
			catch (Exception ex)
			{
                throw new ApplicationException("无效的组地址(" + s + ")。", ex);
			}

			return new GroupAddress(arrGroupAddr);
		}
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct DeviceAddress
	{
		[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
		public readonly byte[] deviceAddress;

        public DeviceAddress(byte[] deviceAddress)
        {
            if (deviceAddress != null && deviceAddress.Length == 4)
            {
                this.deviceAddress = deviceAddress;
            }
            else
            {
                throw new ApplicationException("无效的设备地址：" + System.Text.Encoding.UTF8.GetString(deviceAddress));
            }
        }
		/// <summary>
		/// 创建一个设备地址
		/// </summary>
		/// <param name="deviceAddress">字符串格式的设备地址</param>
		public DeviceAddress(string deviceAddress)
		{
			this.deviceAddress = Parse(deviceAddress).GetBytes();
		}

		/// <summary>
		/// 获取设备地址的字节表示
		/// </summary>
		/// <returns></returns>
		public byte[] GetBytes()
		{
			return this.deviceAddress;
		}

		public override string ToString()
		{
            //ushort type = BitConverter.ToUInt16(deviceAddress, 1);
            //return String.Format("{0:000}{1:000}{2:000}", deviceAddress[0], type, deviceAddress[3]);
            if (deviceAddress[0] == 0x00)//指令场景地址
            {
                return String.Format("{0}.{1}.{2}", deviceAddress[1], deviceAddress[2], deviceAddress[3]);
            }
            else
            {
                ushort type = BitConverter.ToUInt16(deviceAddress, 2);
                return String.Format("{0:000}{1:000}{2:000}", deviceAddress[0], deviceAddress[1], type);
            }
        }

		public static DeviceAddress Parse(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				throw new ArgumentNullException("s");
			}
			byte[] arrDeviceAddr = new byte[4] { 0, 0, 0, 0 };
			try
            {
                arrDeviceAddr[0] = Convert.ToByte(s.Substring(0, 3));
                arrDeviceAddr[1] = Convert.ToByte(s.Substring(3, 3));
                byte[] modalType = BitConverter.GetBytes(Convert.ToUInt16(s.Substring(6, 3)));
                arrDeviceAddr[2] = modalType[0];
                arrDeviceAddr[3] = modalType[1];
			}
			catch (Exception ex)
			{
				throw new ApplicationException("无效的设备地址。", ex);
			}

			return new DeviceAddress(arrDeviceAddr);
		}
	}
}
