using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace RIMSI_Audio_multiplayer
{
    class GameStatus
    {
        public struct CharacterState
        {
            public int skeletonId;
            public String name;
            public bool isPresent;
            public double Z;
        }

        public static string ANESTH_NAME = "anesthesiologist";
        public static string SURGEON_NAME = "surgeon";
        public static string NURSE_NAME = "nurse";
        public static string NO_CHARACHTER = "none";

        public static string INTERACTION_VOICE = "voice";
        public static string INTERACTION_GESTURE = "gesture";

        public CharacterState activeCharacter;

        public string expectedCharacterName = GameStatus.NO_CHARACHTER;
        public string talkingPlayer = GameStatus.NO_CHARACHTER;
        public string[]  expectedCommand = {""};
        public string expectedCommandID = "";
        public string commandType = ""; // Gesture or Vocal

        public CharacterState anestState;
        public CharacterState surgeonState;
        public CharacterState nurseState;

        public bool waitingForAnswer = false;

        private static GameStatus instance;

        private GameStatus() 
        {
            anestState.name = GameStatus.ANESTH_NAME;
            anestState.skeletonId = -1;
            anestState.isPresent = false;
            anestState.Z = double.MaxValue;

            surgeonState.name = GameStatus.SURGEON_NAME;
            surgeonState.skeletonId = -1;
            surgeonState.isPresent = false;
            surgeonState.Z = double.MaxValue;

            nurseState.name = GameStatus.NURSE_NAME;
            nurseState.skeletonId = -1;
            nurseState.isPresent = false;
            nurseState.Z = double.MaxValue;

            activeCharacter.name = GameStatus.NO_CHARACHTER;
            activeCharacter.skeletonId = -1;
            activeCharacter.isPresent = false;
            activeCharacter.Z = double.MaxValue;
        }

        public static GameStatus Instance
        {
            get 
            {
                if (instance == null)
                {
                    instance = new GameStatus();
                }
                return instance;
            }
        }

        public void ParseUpdateStatus(string msg)
        { 
            string[] splitMsg = msg.Split('@');
            string cmd = splitMsg[0];
            
            switch (cmd)
            { 
                case "rimsiQuestion":
                    
                    JObject parJSON = JObject.Parse(splitMsg[1]);
                    //TODO update expectedCharacter and expectedCommand rimsiQuestion@{ "answer": "Federico Pernici", "id": "1" }
                    expectedCommand = ((string)parJSON.SelectToken("answer")).Split(',');
                    expectedCharacterName = (string)parJSON.SelectToken("player");
                    expectedCommandID = (string)parJSON.SelectToken("id");
                    commandType = (string)parJSON.SelectToken("type");
                    waitingForAnswer = true;
                    break;
                default:
                    break;
            }
        }

        public bool checkExpectedCommand(string command) 
        {
            if (expectedCommand.Contains(command))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void popExpectedCommand(string command)
        {
            if (expectedCommand.Contains(command))
            {
                expectedCommand = expectedCommand.Where(val => val != command).ToArray();

            }
        }

        public void notifyAnswer(bool recognized, string answer = "") 
        {
            if (waitingForAnswer)
            {
                SocketManager.Instance.WriteOnSocket(
                       "rimsiAnswer@{\"id\" : \"" + this.expectedCommandID + "\", \"correct\" : \"" + recognized + "\", \"answer\" : \"" + answer + "\"}");
                
                //if command is correct, put the question/answer system in idle state
                waitingForAnswer = !recognized || expectedCommand.Length >0;
            }
        }


        public bool isCorrectSpeaker() 
        {
            return this.talkingPlayer == this.expectedCharacterName;
        }

        public bool isHandTrackingActive()
        {
            return this.commandType == GameStatus.INTERACTION_GESTURE;
        }

    }
}
