using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HttpServer.HttpModules;
using System.IO;
using HttpServer;
using HttpServer.Sessions;
using System.Diagnostics;
using System.Threading;
using System.Web.Script.Serialization;
using EMDServer.Common;

namespace EMDWebserver
{
    public class EmdWebInterface : HttpModule , iEMDConnection
    {
        #region Class variables
        // ----------------------------------------
        public bool upOrDown = true;
        public static byte value = 0;

        // JSON Serializer
        JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
        // Old Response reference 
        IHttpResponse responseRef;

        private MobileManager mobileManager;
        // ----------------------------------------
        #endregion

        #region Public methods
        // ----------------------------------------
        /// <summary>
        /// Creates a new instance of the class
        /// </summary>
        public EmdWebInterface()
        {
            mobileManager = new MobileManager();

            //Debug.WriteLine("EMDWEBINTERFACE - Instantiated...");
        }

        /// <summary>
        /// Method that process the URL
        /// </summary>
        /// <param name="request">Information sent by the browser about the request</param>
        /// <param name="response">Information that is being sent back to the client.</param>
        /// <param name="session">Session used to </param>
        /// <returns>true if this module handled the request.</returns>
        public override bool Process(IHttpRequest request, IHttpResponse response, IHttpSession session)
        {
            //Debug.WriteLine("EMDWEBINTERFACE - Processing request...");          

            // set reference
            responseRef = response;
                        
            if (request.Form.Name.Equals("QueryString"))
            {
                try
                {
                    // deserialize json string to command object
                    Command[] recvdCmds = jsSerializer.Deserialize<Command[]>(request.Form[""].ToString("", true).Substring(1));
                    
                    // call event for each received command
                    for (int i = 0; i < recvdCmds.Length; i++)
                    {
                        onCommandReceived(recvdCmds[i]);

                        //Debug.WriteLine("EMDWEBINTERFACE - New command received!");
                    }

                    for (int i = 0; i < recvdCmds.Length; i++)
                    {
                        if (this.mobileManager.isCallbackCommand(recvdCmds[i]))
                        {
                            SortedDictionary<int, Command> commands = this.mobileManager.getActualCommands(request.RemoteEndPoint.Address.ToString());
                            //Command cmd = new Command(11, 13, new byte[] { 2, 3, 5, 1 });

                            if (commands.Count > 0)
                            {
                                Command[] cmds = new Command[commands.Count];

                                for (int j = 0; j < commands.Count; j++)
                                {
                                    cmds[j] = commands.ElementAt(j).Value;
                                }

                                string jsonData = jsSerializer.Serialize(cmds);

                                //jsonData = "[" + jsonData + "]";

                                responseRef.ContentLength = (long)Encoding.UTF8.GetBytes(jsonData).Length;
                                responseRef.ContentType = "text/plain";
                                //responseRef.SendHeaders();

                                StreamWriter writer = new StreamWriter(responseRef.Body);
                                writer.Write(jsonData);
                                writer.Flush();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine("EMDWEBINTERFACE - Exception on deserializing command: " + e.Message);
                }

                return true;
            }

            #region Unused
            //if (!string.IsNullOrEmpty(request.Uri.Query))
            //{
            //    //byte query = request.
            //    string queryString = request.Uri.Query;

            //    if (queryString.Contains("?"))
            //    {
            //        queryString = queryString.Substring(queryString.IndexOf("?") + 1);
            //    }
                  
            //    Debug.WriteLine("EMDWEBINTERFACE - QueryString=" +queryString);

            //    if ("1.5/2.5" == queryString)
            //    {
            //        JavaScriptSerializer serializer = new JavaScriptSerializer();                    
            //        float[] floats = new float[2];
            //        floats[0] = (float)rand.NextDouble();
            //        floats[1] = (float)rand.NextDouble();
            //        string json = serializer.Serialize(floats);


            //        response.ContentLength = (long)Encoding.UTF8.GetBytes(json).Length;
            //        response.SendHeaders();

            //        StreamWriter writer = new StreamWriter(response.Body);
            //        writer.Write(json);
            //        writer.Flush();
            //    }
            //    return true;
            //}
            //else
            #endregion
            
            else if (request.Uri.AbsolutePath.EndsWith("/") | request.Uri.AbsolutePath.Contains("index.html"))
            {
                BinaryReader reader = null;
                try
                {
                    FileStream stream = File.Open(Path.Combine(Path.Combine(Environment.CurrentDirectory, "http"), "EMD.html"), FileMode.Open);
                    reader = new BinaryReader(stream);
                    long size = reader.BaseStream.Length;
                    long count = 0;
                    byte[] data = new byte[1024];

                    while (count < size)
                    {
                        int readSize = data.Length;

                        if ((count + data.Length) > size)
                        {
                            readSize = (int)(size - (long)count);
                        }

                        reader.Read(data, 0, readSize);
                        response.Body.Write(data, 0, readSize);
                        count += readSize;
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine("EMDWEBINTERFACE - Exception on processing request: " + e.Message);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }

                return true;
            }
            else
            {
                return false;
            }            

            #region Samplecode
            //if (session["times"] == null)
            //    session["times"] = 1;
            //else
            //    session["times"] = ((int)session["times"]) + 1;
        #endregion
        }
        // ----------------------------------------
        #endregion

        #region iEMDConnection Members
        // ----------------------------------------
        public event EventHandler<CommandHandler> cmdReceived;

        public bool openConnection()
        {
            return false;
        }

        public bool closeConnection()
        {
            return false;
        }

        public void sendCommand(Command cmd)
        {
            if (responseRef != null)
            {
                try
                {
                    this.mobileManager.addCommand(cmd.Id, cmd);
                }
                catch (Exception e)
                {
                    Debug.WriteLine("EMDWEBINTERFACE - Exception on sending command, response ref not set: " + e.Message);
                }
            }
        }

        public void onCommandReceived(Command cmd)
        {
            if (cmdReceived != null)
            {
                cmdReceived(this, new CommandHandler() { cmd = cmd });
            }
        }
        // ----------------------------------------
        #endregion
    }
}
