using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Threading;

[assembly: Addin("BasicPathFindingModule", "0.1")]
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
namespace OpenSim.Modules.PathFinding
{
    [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicPathFindingModule")]

    public class BasicPathFindingModule : INonSharedRegionModule
    {
        #region Region Module
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private Scene m_scene = null;
        private IConfig m_config = null;
        private bool m_enabled = true;
        private string m_dataDirectory = "./PathFindingData";
        private IScriptModuleComms m_scriptModule;

        public string Name
        {
            get { return "BasicPathFindingModule"; }
        }

        public Type ReplaceableInterface
        {
            get { return null; }
        }

        public void AddRegion(Scene scene)
        {

        }

        public void Close()
        {

        }

        public void Initialise(IConfigSource source)
        {
            try
            {
                m_config = source.Configs["XEngine"];

                if (m_config != null)
                {
                    m_dataDirectory = m_config.GetString("PathFindingDataDirectory", m_dataDirectory);
                    m_enabled = m_config.GetBoolean("EnablePathFinding", m_enabled);
                }
                else
                {
                    m_log.Error("[" + Name + "]: Cant find config.");
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[" + Name + "]: initialization error: {0}", e.Message);
                return;
            }

            if (m_enabled)
            {
                m_log.Info("[" + Name + "]: module is enabled");
            }
            else
            {
                m_log.Info("[" + Name + "]: module is disabled");
            }
        }

        public void RegionLoaded(Scene scene)
        {
            if (m_enabled)
            {
                m_log.Info("[" + Name + "]: Load region " + scene.Name);

                m_scene = scene;
                m_scriptModule = m_scene.RequestModuleInterface<IScriptModuleComms>();
                if (m_scriptModule == null)
                {
                    m_log.ErrorFormat("[" + Name + "]: Failed to load IScriptModuleComms!");
                    m_enabled = false;
                    return;
                }

                try
                {
                    m_scriptModule.RegisterScriptInvocation(this, "osCreateNewPathFindingScene");
                    //m_scriptModule.RegisterScriptInvocation(this, "osAddObjectToPathFindingScene");
                    //m_scriptModule.RegisterScriptInvocation(this, "osGetPath");
                }
                catch (Exception e)
                {
                    m_log.WarnFormat("[" + Name + "]: script method registration failed; {0}", e.Message);
                    m_enabled = false;
                }

                m_log.Info("[" + Name + "]: Region loading done!");
            }
        }

        public void RemoveRegion(Scene scene)
        {

        }

        #endregion

        #region Script Funktions

        private void createPathFindingScene(String imageName)
        {
            Bitmap _map = new Bitmap((int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY);

            PathFindingSceneGenerator.DrawObjectVolume(m_scene, ref _map);

            _map.Save(imageName + ".png", ImageFormat.Png);


            return;
        }

        [ScriptInvocation]
        public string osCreateNewPathFindingScene(UUID hostID, UUID scriptID)
        {
            m_log.Info("[" + Name + "]: Create new Pathfinding scene!");

            String imageName = UUID.Random().ToString();

            try
            {
                SceneObjectGroup _host = m_scene.GetSceneObjectGroup(hostID);

                if (_host != null)
                {
                    (new Thread(delegate () { createPathFindingScene(imageName); })).Start();
                }
                else
                {
                    m_log.ErrorFormat("[" + Name + "]: Host is null");
                }
            }
            catch(Exception _error)
            {
                m_log.Error(_error.Message);
                m_log.Error(_error.StackTrace);
            }

            return imageName;

        }
        #endregion

    }
}