/* Commands.cs
 * © Andrey Bushman, 2016
 * The example of the commands behaviour changing.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
 
#if AUTOCAD
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
#endif
 
[assembly: CommandClass(typeof(Bushman.CAD.Sandbox.Commands))]
 
namespace Bushman.CAD.Sandbox {
 
    // ************************************************************************
 
    static class Tools {
        public static void Do(MethodInfo mi, Dictionary<string, Action> dict) {
            if (null == dict) {
                throw new ArgumentNullException("dict");
            }
 
            string key = GetKey(mi);
 
            if (dict.ContainsKey(key) && null != dict[key]) {
                dict[key]();
            }
            else {
                String msg = String.Format("Either the dictionary hasn't '{0}' " +
                    "key or the record's value is NULL.", key);
                throw new ArgumentException(msg);
            }
        }
 
        public static string GetKey(MethodInfo mi) {
            if (null == mi) {
                throw new ArgumentNullException("mi");
            }
 
            CommandMethodAttribute att = mi.GetCustomAttributes(
                typeof(CommandMethodAttribute), false).FirstOrDefault()
                as CommandMethodAttribute;
 
            if (null == att) {
                String msg = String.Format("Method '{0}' hasn't " +
                    "'CommandMethod' attribute.", mi.Name);
                throw new ArgumentException(msg);
            }
 
            string format = null == att.GroupName ||
                att.GroupName.Trim() == String.Empty ? "{1}" : "{0}.{1}";
            string key = String.Format(format, att.GroupName.Trim().ToLower(),
                att.GlobalName.Trim().ToLower());
            return key;
        }
    }
 
    // ************************************************************************
    sealed class Operations {
        public static void Operation_01() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            WriteHelloMessage(mi);
        }
 
        public static void Operation_02() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            WriteHelloMessage(mi);
        }
 
        public static void Operation_03() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            WriteHelloMessage(mi);
        }
 
        public static void Operation_04() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            WriteHelloMessage(mi);
        }
 
        private static void WriteHelloMessage(MethodInfo mi) {
            if (null == mi) {
                throw new ArgumentNullException("mi");
            }
 
            Document doc = cad.DocumentManager.MdiActiveDocument;
            if (null == doc) {
                return;
            }
 
            Editor ed = doc.Editor;
            ed.WriteMessage("Hello from {0}!\n", mi.Name);
        }
    }
 
    // ************************************************************************
    public sealed class Commands {
 
        const string groupName = "bushman";
        static Dictionary<string, Action> dict = new Dictionary<string,
            Action>();
 
        static Commands() {
            if (dict.Count == 0) {
                dict.Add(groupName + ".test1", Operations.Operation_01);
                dict.Add(groupName + ".test2", Operations.Operation_02);
            }
        }
 
        [CommandMethod(groupName, "Test1", CommandFlags.Modal)]
        public static void Test1() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            Tools.Do(mi, dict);
        }
 
        [CommandMethod(groupName, "Test2", CommandFlags.Modal)]
        public static void Test2() {
            MethodInfo mi = (MethodInfo)MethodBase.GetCurrentMethod();
            Tools.Do(mi, dict);
        }
 
        [CommandMethod(groupName, "ChangeCmd", CommandFlags.Modal)]
        public void ChangeCmd() {
            string key = "bushman.test1";
            dict[key] = dict[key] == Operations.Operation_01 ?
                (Action)Operations.Operation_03 : Operations.Operation_01;
            key = "bushman.test2";
            dict[key] = dict[key] == Operations.Operation_02 ?
                (Action)Operations.Operation_04 : Operations.Operation_02;
        }
    }
}