﻿/*
using System;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;

using System.Text;
using System.Threading;
using System.Net.WebSockets;

namespace Tap.Tilt
{
    [Serializable]
    public class SocketMessage
    {
        public string messageType
    }

    // Handles all socketio network transport
    [RequireComponent(typeof(GameController))]
    [RequireComponent(typeof(GameData))]

    public class WebsocketNetwork : MonoBehaviour
    {
        // static instance of self
        public static WebsocketNetwork instance;

        // A text mesh which shows the root of the selected url to the users
        public TextMesh showUrl;

        // The game controller where the data is sent to manage the game
        private GameController gc;

        // The game data to use for this instance
        private GameData gameData;

        private ClientWebSocket Socket;

        // number of seconds between server pings
        private readonly float pingDelay = 5.0f;

        // The last ping time
        private float lastPing = 0f;

        // Set to true when connected
        private bool connectState = false;

        // Reconnect interval for reconnect attempts
        private readonly float reconnectInterval = 1f;
        private float lastAttempt;

        /// <summary>
        /// Cached list to spare some GC alloc.
        /// </summary>
        private List<object> arguments = new List<object>();

        // Create events for the server to respond to
        void OnEnable()
        {
            instance = this;
            gc = GetComponent<GameController>();
            gameData = GetComponent<GameData>();
            SocketSetup();
        }

        async void SocketConnect()
        {
            Socket = new ClientWebSocket();
            try
            {
                await Socket.ConnectAsync(new Uri(gameData.socketUrl), CancellationToken.None);
                if (Socket.State == WebSocketState.Open)
                {
                    connectState = true;
                    Debug.Log("Connected Websocket");
                }
            }
            catch (Exception e)
            {
                Debug.Log("Connect Socket Failed" + e.Message);
            }
        }

        public void Emit(string eventName, params object[] args)
        {
            arguments.Clear();
            arguments.Add(eventName);

            // Find and swap any binary data(byte[]) to a placeholder string.
            // Server side these will be swapped back.
            List<byte[]> attachments = null;
            if (args != null && args.Length > 0)
            {
                int idx = 0;
                for (int i = 0; i < args.Length; ++i)
                {
                    byte[] binData = args[i] as byte[];
                    if (binData != null)
                    {
                        if (attachments == null)
                            attachments = new List<byte[]>();

                        Dictionary<string, object> placeholderObj = new Dictionary<string, object>(2);
                        placeholderObj.Add(Packet.Placeholder, true);
                        placeholderObj.Add("num", idx++);

                        arguments.Add(placeholderObj);

                        attachments.Add(binData);
                    }
                    else
                        arguments.Add(args[i]);
                }
            }

            string payload = null;

            try
            {
                payload = Manager.Encoder.Encode(arguments);
            }
            catch (Exception ex)
            {
                (this as ISocket).EmitError(SocketIOErrors.Internal, "Error while encoding payload: " + ex.Message + " " + ex.StackTrace);

                return this;
            }

            // We don't use it further in this function, so we can clear it to not hold any unwanted reference.
            arguments.Clear();

            if (payload == null)
                throw new ArgumentException("Encoding the arguments to JSON failed!");

            int id = 0;

            if (callback != null)
            {
                id = Manager.NextAckId;

                if (AckCallbacks == null)
                    AckCallbacks = new Dictionary<int, SocketIOAckCallback>();

                AckCallbacks[id] = callback;
            }

            Packet packet = new Packet(TransportEventTypes.Message,
                                       attachments == null ? SocketIOEventTypes.Event : SocketIOEventTypes.BinaryEvent,
                                       this.Namespace,
                                       payload,
                                       0,
                                       id);

            if (attachments != null)
                packet.Attachments = attachments; // This will set the AttachmentCount property too.

            (Manager as IManager).SendPacket(packet);

            return this;
        }
        /// <summary>
        /// Identify this instance.
        /// </summary>
        async void Identify()
        {
            // Check if there's a saved identity for this instance
            // Attach the unity id to the identity
            string identity = PlayerPrefs.GetString("deviceUniqueIdentifier", SystemInfo.deviceUniqueIdentifier);

            // Save the id
            PlayerPrefs.SetString("deviceUniqueIdentifier", identity);

            // Send the identity of this server
            ArraySegment<byte> b = new ArraySegment<byte>(Encoding.UTF8.GetBytes("hello"));
            await Socket.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None);


            Socket.Emit("identify", JsonUtility.ToJson(identity));
        }

        public void SocketEvents()
        {
            // Add error handler, so we can display it
            Socket.On(SocketIOEventTypes.Error, OnError);

            // Set up our event handlers.
            Socket.On(SocketIOEventTypes.Connect, OnConnected);

            Socket.On(SocketIOEventTypes.Disconnect, OnDisconnected);

            // Generic control changes
            Socket.On("control", (socket, packet, args) =>
            {
                // Debug.Log("control event on socket" + packet.ToString());

                ControlData cd = JsonUtility.FromJson<ControlData>(MessageData(packet.ToString()));

                // Send the control data to the Game Controller
                gc.UserControl(cd);
            });

            // User requests an orientation reset
            Socket.On("reset", (socket, packet, args) =>
            {
                ControlData cd = JsonUtility.FromJson<ControlData>(MessageData(packet.ToString()));
                gc.UserReset(cd.i);
            });

            Socket.On("controlsDisconnect", (socket, packet, args) =>
            {
                Debug.Log("disconnect event on socket" + packet.ToString());
                gc.UserExit(MessageData(packet.ToString().Replace("\"", "")));
            });

        }

        public void SocketSetup()
        {

            // Show the user URL
            if (showUrl != null)
                showUrl.text = gameData.shortLink == "" ? gameData.socketUrl.Replace("/socket.io/display", "") : gameData.shortLink;
        }

        /// <summary>
        /// Socket connected event.
        /// </summary>
        private void OnConnected(Socket socket, Packet packet, params object[] args)
        {
            Debug.Log("OnConnected");
            connectState = true;
            Identify();
        }
        private void OnDisconnected(Socket socket, Packet packet, params object[] args)
        {
            Debug.Log("DISCONNECTED");
            connectState = false;
        }

        private void LateUpdate()
        {
            // If not connected the try to reconnect at the interval rate
            if (!connectState && lastAttempt + reconnectInterval < Time.time)
            {
                lastAttempt = Time.time;
                SocketConnect();
                SocketEvents();
            }
        }
 
        /// <summary>
        /// Called on local or remote error.
        /// </summary>
        private void OnError(Socket socket, Packet packet, params object[] args)
        {
            Error error = args[0] as Error;
            switch (error.Code)
            {
                case SocketIOErrors.User:
                    Debug.Log("Exception in an event handler!");
                    break;
                case SocketIOErrors.Internal:
                    Debug.Log("Internal error!");
                    break;
                default:
                    Debug.Log("Server error! " + error.Code.ToString() + " " + error.Message.ToString());
                    break;
            }
            Debug.Log(error.ToString());
        }

        public void Send(string eventName, params object[] data)
        {
            // Debug.Log("Socket Send " + eventName + data.ToString());
            Socket.Emit(eventName, data);
        }

        // A sender which sends an event to one multiplayer target
        public void SendEvent(string connectionId, string eventName, string eventValue)
        {
            // Debug.Log("SendEvent " + connectionId + " eventName: " + eventName + " value: " + eventValue.ToString());

            Socket.Emit("event", connectionId, eventName, eventValue);
        }

        // Helper to extract data from JSON encoded strings
        private string MessageData(string message)
        {
            int startIndex = message.IndexOf(",");
            return (startIndex >= 1) ? message.Substring(startIndex + 1, message.Length - (startIndex + 2)) : "";
        }

        // Update is called once per frame
        void Update()
        {
            if (RootSocket != null && lastPing + pingDelay > Time.time)
            {
                lastPing = Time.time;
                RootSocket.Emit("ping");
            }
        }
    }
}
*/