private void PopulateGrid_Properties(DataGridView grid, bool abbreviated, BindingFlags bindingFlags)
        {
            Type objType = null;

            if (Scope == null)
            {
                objType = TclAPI.GetCsTypeFromName(ScopeStr);
                if (objType == null)
                {
                    return;
                }
            }
            else
            {
                objType = Scope.GetType();
            }

            PropertyInfo[] properties = objType.GetProperties(bindingFlags);
            foreach (var property in properties)
            {
                object   value = property.GetValue(Scope, null);
                string[] row   = new string[]
                {
                    property.Name,
                    value == null ? "null" : value.ToString(),
                    abbreviated ? property.PropertyType.Name : property.PropertyType.ToString()
                };
                grid.Rows.Add(row);
            }
        }
        private void PopulateGrid_Methods(DataGridView grid, bool abbreviated, BindingFlags bindingFlags)
        {
            Type objType = null;

            if (Scope == null)
            {
                objType = TclAPI.GetCsTypeFromName(ScopeStr);
                if (objType == null)
                {
                    return;
                }
            }
            else
            {
                objType = Scope.GetType();
            }

            RelevantEnums = new List <Type>();

            MethodInfo[] methods = objType.GetMethods(bindingFlags);
            foreach (var method in methods)
            {
                if (MethodRows == null)
                {
                    MethodRows = new Dictionary <DataGridViewRow, MethodInfo>();
                }

                string          parameters = "";
                ParameterInfo[] p          = method.GetParameters();
                for (int i = 0; i < p.Length; i++)
                {
                    // Record relevant enums
                    if (p[i].ParameterType.IsEnum)
                    {
                        RelevantEnums.Add(p[i].ParameterType);
                    }

                    parameters += "[" +
                                  (abbreviated ? p[i].ParameterType.Name : p[i].ParameterType.ToString())
                                  + " " + p[i].Name + "]";
                    if (i + 1 < p.Length)
                    {
                        parameters += ", ";
                    }
                }

                string[] row = new string[]
                {
                    method.Name,
                    parameters,
                    abbreviated ? method.ReturnType.Name : method.ReturnType.ToString()
                };

                int ind = grid.Rows.Add(row);
                MethodRows.Add(grid.Rows[ind], method);
            }
        }
        public static unsafe int Cs(IntPtr clientData, IntPtr interp, int objc, IntPtr *argv)
        {
            Program.mainInterpreter.ErrorMessage = "";

            if (objc < 3)
            {
                Program.mainInterpreter.ErrorMessage =
                    "Not enough parameters provided for the command." + NL +
                    "Correct command format: 'cs $object $member $parameters'." + NL +
                    "For more info type 'cshelp'.";
                return(TclInterpreter.TCL_ERROR);
            }

            Type   objType = null;
            object obj     = TclAPI.FindCsObject(argv[1]);

            if (obj == null)
            {
                string str = TclAPI.GetCsString(argv[1]);

                objType = TclAPI.GetCsTypeFromName(str);

                if (objType == null)
                {
                    Program.mainInterpreter.ErrorMessage =
                        "The parameter '" + str + "' could not be linked to any C# object or type.";
                    return(TclInterpreter.TCL_ERROR);
                }
            }
            else
            {
                objType = obj.GetType();
            }

            object result = null;

            // Required data - can be Method or Property
            string requiredMember = TclAPI.GetCsString(argv[2]);
            IEnumerable <MemberInfo> candidates =
                objType.GetMembers().Where(m => m.Name == requiredMember && TclAPI.IsAPICompatibleMember(m));

            // Method
            if (candidates.FirstOrDefault() is MethodInfo)
            {
                int totalParams = objc - 3;

                IEnumerable <MethodInfo> matchedMethods = candidates.Where(m => m.MemberType == MemberTypes.Method)
                                                          .Cast <MethodInfo>().Where(m => m.GetParameters().Count() == totalParams);

                // Convert the tcl parameters to cs objects
                object[] parameters = new object[totalParams];
                for (int i = 0; i < totalParams; i++)
                {
                    object csObj = TclAPI.Tcl2Cs(argv[3 + i]);
                    if (csObj == null)
                    {
                        string args = "Parameters:" + Environment.NewLine;
                        for (int j = 0; j < objc; j++)
                        {
                            args += j + ": " + TclAPI.GetCsString(argv[j]) + Environment.NewLine;
                        }
                        throw new ArgumentException("Invalid parameter provided at index: " + (3 + i).ToString() + Environment.NewLine + args);
                    }
                    parameters[i] = csObj;
                }

                // Try the candidate methods until one works
                bool success = false;
                foreach (MethodInfo method in matchedMethods)
                {
                    try
                    {
                        result = method.Invoke(obj, parameters);

                        /*if(result != null && !result.GetType().Equals(method.ReturnType))
                         *  Console.WriteLine("Type Difference");*/
                        success = true;
                        break;
                    }
                    catch (Exception) { }
                }

                // If invoked method was void
                if (success)
                {
                    if (result == null)
                    {
                        TclDLL.Tcl_ResetResult(interp);
                        return(0);
                    }
                }
                else
                {
                    Program.mainInterpreter.ErrorMessage +=
                        "No method overload could be executed for the method " + requiredMember + NL;
                }
            }
            // Property
            else if (candidates.Count() == 1 && candidates.FirstOrDefault() is PropertyInfo p)
            {
                result = p.GetValue(obj, null);
            }

            TclDLL.Tcl_SetObjResult(interp, TclAPI.Cs2Tcl(result));

            if (result == null)
            {
                Program.mainInterpreter.ErrorMessage +=
                    "'" + requiredMember + "' returned null.";
                return(TclInterpreter.TCL_WARNING);
            }

            return(0);
        }
        public static unsafe int CsHelp(IntPtr clientData, IntPtr interp, int objc, IntPtr *argv)
        {
            if (objc == 1)
            {
                CsHelp_GUI.CreateDialog();
                return(0);
            }

            if (objc != 2)
            {
                return(1);
            }

            string arg = TclAPI.GetCsString(argv[1]).ToLower();

            string        scopeStr = "";
            object        scopeObj = null;
            List <string> grids    = new List <string>();

            if (arg.Equals(CsHelp_GUI.CSH_SINGLETONS))
            {
                grids.Add(CsHelp_GUI.CSH_SINGLETONS);
                scopeStr = "Singletons";
            }
            else if (arg.Equals(CsHelp_GUI.CSH_ENUMS))
            {
                grids.Add(CsHelp_GUI.CSH_ENUMS);
                scopeStr = "Enums";
            }
            else
            {
                // Try find object
                scopeObj = TclAPI.FindCsObject(argv[1]);
                if (scopeObj != null)
                {
                    grids.Add(CsHelp_GUI.CSH_PROPERTIES);
                    grids.Add(CsHelp_GUI.CSH_METHODS);
                    grids.Add(CsHelp_GUI.CSH_ENUMS);
                    grids.Add(CsHelp_GUI.CSH_PROPERTIES_STATIC);
                    grids.Add(CsHelp_GUI.CSH_METHODS_STATIC);
                    scopeStr = scopeObj.GetType().Name + " - " + scopeObj.GetType().ToString();
                }
                // Try find type
                else
                {
                    Type   objType = null;
                    string str     = TclAPI.GetCsString(argv[1]);

                    objType = TclAPI.GetCsTypeFromName(str);

                    if (objType != null)
                    {
                        grids.Add(CsHelp_GUI.CSH_PROPERTIES_STATIC);
                        grids.Add(CsHelp_GUI.CSH_METHODS_STATIC);
                        scopeStr = objType.FullName;
                    }
                }
            }

            CsHelp_GUI.CreateDialog(grids, scopeStr, scopeObj);

            return(0);
        }