using System;
using Microsoft.SPOT;

namespace WIFI
{
    public abstract class SimpleSocket
    {
        public enum SocketProtocol
        {
            TcpStream = 1,
            UdpDatagram = 2
        }

        public enum SocketFeatures
        {
            TcpStream = 1,
            UdpDatagram = 2,
            NtpClient = 3,
            TcpListener = 4
        }

        // Listens on the port instead of connecting remotely
        public virtual void Listen() { throw new NotImplementedException(); }

        // Returns a timestamp from an NTP server
        // Return the number of seconds since January 1st, 1900
        public virtual double NtpLookup()
        {
            throw new NotImplementedException();
        }

        public virtual string LineEnding { get; set; }

        // Connects to the remote host
        public abstract void Connect(SocketProtocol Protocol = SocketProtocol.TcpStream);

        // Closes the connection
        public abstract void Close();

        // Sends string data to the socket
        public virtual void Send(string Data)
        {
            this.SendBinary(Tools.Chars2Bytes(Data.ToCharArray()));
        }

        // Sends binary data to the socket
        public abstract void SendBinary(byte[] Data);

        // Returns true when connected, otherwise false
        public abstract bool IsConnected { get; }

        // <summary>Returns the hostname this socket is configured for/connected to</summary>
        public abstract string Hostname { get; }
        // <summary>Returns the port number this socket is configured for</summary>
        public abstract ushort Port { get; }

        // Receives data from the socket
        public abstract string Receive(bool Block = false);

        // Receives binary data from the socket (line endings aren't used with this method)
        public abstract byte[] ReceiveBinary(int Length);

        // Requests the amount of bytes available in the buffer
        public abstract uint BytesAvailable { get; }

        // Checks if a feature is implemented
        public virtual bool FeatureImplemented(SocketFeatures Feature)
        {
            return false;
        }
    }
}
