/*
COPYRIGHT (C) 2011 EPISERVER AB

THIS FILE IS PART OF NHUNSPELLCHECKER FOR EPISERVER CMS.
IT IS FREE SOFTWARE: YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU LESSER GENERAL PUBLIC LICENSE VERSION v2.1 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.

NHUNSPELLCHECKER FOR EPISERVER CMS IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU LESSER GENERAL PUBLIC LICENSE FOR MORE DETAILS.
NOTE THAT THIS PROJECT RELIES ON OTHER OPEN SOURCE PROJECTS WITH THEIR OWN RESPECTIVE LICENSES.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using NHunspellSpell = NHunspell; 

namespace EPiServer.Research.Plugins.NHunspell
{

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class rpc : IHttpHandler
    {

        static private bool IsPathSet = false;

        public void ProcessRequest(HttpContext context)
        {
            byte[] buffer = new byte[context.Request.InputStream.Length];
            context.Request.InputStream.Read(buffer,0,(int)context.Request.InputStream.Length);
            string s = System.Text.UTF8Encoding.UTF8.GetString(buffer);
            context.Response.ContentType = "text/plain";

            System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
            RequestObject o = json.Deserialize<RequestObject>(s);
            string selectedLanguage = o.Language;
            string affpath = context.Server.MapPath("~/modules/nhunspellchecker/" + selectedLanguage + "/" + selectedLanguage + ".aff");
            string dicpath = context.Server.MapPath("~/modules/nhunspellchecker/" + selectedLanguage + "/" + selectedLanguage + ".dic");
            
            if (!IsPathSet)
            {
                NHunspellSpell.Hunspell.NativeDllPath = context.Server.MapPath("~/modules/nhunspellchecker/");
                IsPathSet = true;
            }
            if (o.method == "checkWords")
            {
                List<string> r = new List<string>();
                
                using (NHunspellSpell.Hunspell speller = new NHunspellSpell.Hunspell(affpath, dicpath))
                {
                    foreach (string t in o.Words)
                    {
                        if (!speller.Spell(t))
                            r.Add(t);
                    }
                }
                string ret = "";

                ResponseObject resp = new ResponseObject();
                resp.id = null;
                resp.result = r.ToArray();
                resp.error = null;

                ret = json.Serialize(resp);
                context.Response.Write(ret);
            }
            else {
                string wordtospell = o.@params[1] as string;
                if (wordtospell != null)
                {
                    using (NHunspellSpell.Hunspell speller = new NHunspellSpell.Hunspell(affpath, dicpath))
                    {
                        List<string> suggestions = speller.Suggest(wordtospell);

                        SpellResponse sr = new SpellResponse();
                        sr.id = o.id;
                        sr.error = null;
                        sr.result = suggestions.ToArray();

                        string ret = "";
                        ret = json.Serialize(sr);
                        context.Response.Write(ret);
                    }
                }

            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    public class MyKeyPair
    {
        public string key { get; set; }
        public string[] items { get; set; }

    }
    /* request
     * {
     *  "id":"c0",
     *  "method":"checkWords",
     *  "params":["en",
     *              ["TinyMCE","is","a","platform","independent","web","based","Javascript","HTML","WYSIWYG","editor","control","released","as","Open","Source","under","LGPL","by","Moxiecode","Systems","AB","It","has","the","ability","to","convert","TEXTAREA","fields","or","other","elements","instances","very","easy","integrate","into","Content","Management","abc","We","recommend","Firefox","and","Google"]
     *          ]
     * }
     */
    /* result
     * {
     * "id":null,
     * "result":["TinyMCE","Moxiecode","abc","Firefox"],
     * "error":null
     * }
     */

    /* spell request
               * {
               *  "id":"c0",
               *  "method":"getSuggestions",
               *  "params":["en","TinyMCE"]
               * }
               */

    /* spell response
     * {
     *      "id":null,
     *      "result":["Titmice","Times","Tines","Tinnies","Timmy\'s"],
     *      "error":null
     * }
     */
    public class SpellRequest
    {
        public string id { get; set; }
        public string method { get; set; }
        public string[] @params { get; set; }        
    }

    public class SpellResponse
    {
        public string id { get; set; }
        public string[] result { get; set; }
        public string error { get; set; }
    }

    public class ResponseObject
    {
        public string id { get; set; }
        public string[] result { get; set; }
        public string error { get; set; }
    }
    public class RequestObject
    {
        public string id { get; set; }
        public string method { get; set; }
        public object[] @params { get; set; }
        public string Language
        {
            get {
                return (string)@params[0];
            }
        }

        public string[] Words {
            get
            {
                object[] o = (object[])@params[1];

                List<string> list = new List<string>();
                foreach (object oitem in o)
                    list.Add(oitem as string);
                return list.ToArray();
            }
        }
    }
}
