using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using nft.util;
using nft.ui.mainframe_old;
using nft.framework;
using System.Xml;
using System.Diagnostics;
using nft.framework.plugin;

namespace nft.ui.command {
    public class CommandManager {
        public const char IDSuffixSepalator = '#';
        public static readonly CommandManager TheInstance = new CommandManager();

        protected ImageListIndexResolver imgCahce;
        protected Dictionary<string, CommandUI> commands;

        protected CommandManager() {
            commands = new Dictionary<string, CommandUI>();
            imgCahce = new ImageListIndexResolver();
        }

        public static string MakeKey(IHasNameAndID owner, string suffix) {
            if (suffix != null && suffix.Length > 0)
                return owner.ID.AsString + IDSuffixSepalator + suffix;
            else
                return owner.ID.AsString;
        }

        [Obsolete]
        public void RegisterCommand(IHasNameAndID owner, string suffix, CommandUI cui, CommandPathHint menubar, CommandPathHint toolbar) {
            if (toolbar != null)
                Main.mainFrame.ToolBarController.AddToolButton(cui, toolbar);
            if (menubar != null)
                Main.mainFrame.MenuBarController.AddMenuItem(cui, menubar);
            RegisterCommand(suffix, owner, cui);
        }
        [Obsolete]
        public void RegisterCommand(IHasNameAndID owner, string suffix, CommandUI cui, CommandPathHint menubar) {
            RegisterCommand(owner, suffix, cui, menubar, null);
        }
        [Obsolete]
        public void RegisterCommand(IHasNameAndID owner, CommandUI cui, CommandPathHint menubar, CommandPathHint toolbar) {
            RegisterCommand(owner, null, cui, menubar, toolbar);
        }
        [Obsolete]
        public void RegisterCommand(IHasNameAndID owner, CommandUI cui, CommandPathHint menubar) {
            RegisterCommand(owner, null, cui, menubar, null);
        }

        public void RegisterCommand(string name, IHasNameAndID owner, CommandUI cui) {
            string key = MakeKey(owner, name);
            if (commands.ContainsKey(key)) {
                Debug.WriteLine("command key=" + key + " will be overwritten.");
            }
            try {
                commands[key] = cui;
            } catch (Exception e) {
                Debug.WriteLine(cui);
            }
        }

        public void BindCommand(Contribution contrib, string suffix, ICommandProcedure procedure, ParamsReader commandNode) {            
            Debug.Assert(procedure != null && contrib != null && commandNode != null, "Invalid Command is going to regist!");
            string key = MakeKey(contrib, suffix);
            CommandUI ui = FindOrCreateUI(key, commandNode);
            string bar = commandNode["toolbar"].InnerTextOr("MAIN");
            string bid = commandNode["button"].InnerText;
            string mpath = commandNode["menupath"].InnerText;
            if (bid != null)
                Main.mainFrame.ToolBarController.BindCommand(procedure, ui, CommandPathHelper.CombinePath(bar, bid));
            if (mpath != null)
                Main.mainFrame.MenuBarController.BindCommand(procedure, ui, mpath);
        }

        public CommandUI FindOrCreateUI(string cmdKey, ParamsReader reader) {
            CommandUI ui = FindUI(cmdKey);
            if (ui == null && !reader["name"].IsNull) {
                ui = new TriggerCommandUI(reader["name"].InnerText, reader["description"].InnerText, null);
            }
            return ui;
        }

        public CommandUI FindUI(string cmdKey) {
            CommandUI ui = null;

            if (this.commands.TryGetValue(cmdKey, out ui)) {
                return ui;
            } else {
                return null;
            }
        }
    }

}