/*
 * Core.cs --
 *
 * Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 */

using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using Eagle._Attributes;
using Eagle._Components.Private;
using Eagle._Components.Public;
using Eagle._Constants;
using Eagle._Containers.Public;
using Eagle._Interfaces.Public;

namespace Eagle._Plugins
{
    [ObjectId("416b7692-6f4d-472b-be6c-f2da391bee87")]
#if NATIVE
    [PluginFlags(
        PluginFlags.Primary | PluginFlags.System |
        PluginFlags.Host | PluginFlags.Command |
        PluginFlags.Function | PluginFlags.Trace |
        PluginFlags.Policy | PluginFlags.Resolver |
        PluginFlags.Static | PluginFlags.NativeCode |
        PluginFlags.NoPolicies | PluginFlags.NoTraces)]
#else
    [PluginFlags(
        PluginFlags.Primary | PluginFlags.System |
        PluginFlags.Host | PluginFlags.Command |
        PluginFlags.Function | PluginFlags.Trace |
        PluginFlags.Policy | PluginFlags.Resolver |
        PluginFlags.Static | PluginFlags.NoPolicies |
        PluginFlags.NoTraces)]
#endif
    internal sealed class Core : Default
    {
        #region Public Constructors
        public Core(
            IPluginData pluginData
            )
            : base(pluginData)
        {
            //
            // NOTE: This plugin adds the "core" command set into the specified
            //       interpreter.  These commands will typically always be
            //       available in a given interpreter; however, this is not
            //       absolutely guaranteed as they can be explicitly unloaded.
            //
            this.Flags |= AttributeOps.GetPluginFlags(GetType().BaseType) |
                AttributeOps.GetPluginFlags(this);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IState Members
        public override ReturnCode Terminate(
            Interpreter interpreter,
            IClientData clientData,
            ref Result result
            )
        {
            //
            // HACK: Cleanup the core plugin token in the interpreter
            //       state because this is the only place we can be
            //       100% sure it will get done.
            //
            if (interpreter != null)
                interpreter.InternalCorePluginToken = 0;

            return base.Terminate(interpreter, clientData, ref result);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IPlugin Members
        public override Stream GetStream(
            Interpreter interpreter,
            string name,
            ref Result error
            )
        {
            if (String.IsNullOrEmpty(name))
            {
                error = "invalid stream name";
                return null;
            }

            Assembly assembly = this.Assembly;

            if (assembly == null)
            {
                error = "plugin assembly not available";
                return null;
            }

            try
            {
                Stream stream = assembly.GetManifestResourceStream(
                    PathOps.MakeRelativePath(name, true));

                if (stream != null)
                    return stream;
                else
                    error = "stream not found";
            }
            catch (Exception e)
            {
                error = e;
            }

            return null;
        }

        ///////////////////////////////////////////////////////////////////////

        public override string GetString(
            Interpreter interpreter,
            string name,
            CultureInfo cultureInfo,
            ref Result error
            )
        {
            if (interpreter != null)
            {
                return interpreter.GetString(
                    this, name, cultureInfo, ref error);
            }
            else
            {
                error = "invalid interpreter";
            }

            return null;
        }

        ///////////////////////////////////////////////////////////////////////

        public override ReturnCode About(
            Interpreter interpreter,
            ref Result result
            )
        {
            result = FormatOps.PluginAbout(this, false);
            return ReturnCode.Ok;
        }

        ///////////////////////////////////////////////////////////////////////

        public override ReturnCode Options(
            Interpreter interpreter,
            ref Result result
            )
        {
            result = new StringList(DefineConstants.OptionList, false);
            return ReturnCode.Ok;
        }
        #endregion
    }
}
