func BitFlagsTypeFromString(bflg *int64, str string, et reflect.Type, n int) error {
	flgs := strings.Split(str, "|")
	evv := reflect.New(et)
	var err error
	for _, flg := range flgs {
		err = SetEnumValueFromString(evv, flg)
		if err == nil {
			evi := EnumIfaceToInt64(evv.Interface())
			bitflag.Set(bflg, int(evi))
		}
	}
	return err
}
BitFlagsTypeFromString sets an int64 of bit flags from a string representation
of the bits that are set -- gets enum type and n of defined elements directly
package kit
import (
	"bytes"
	"fmt"
	"log"
	"reflect"
	"strings"
	"github.com/goki/ki/bitflag"
)
type EnumRegistry struct {
	Enums map[string]reflect.Type
	Props map[string]map[string]interface{}
	Vals map[string][]EnumValue
}
var Enums EnumRegistry
const (
	BitFlag = true
	NotBitFlag = false
)
func (tr *EnumRegistry) AddEnum(en interface{}, bitFlag bool, props map[string]interface{}) reflect.Type {
	if tr.Enums == nil {
		tr.Enums = make(map[string]reflect.Type)
		tr.Props = make(map[string]map[string]interface{})
		tr.Vals = make(map[string][]EnumValue)
	}
	typ := PtrType(reflect.TypeOf(en)).Elem()
	n := EnumIfaceToInt64(en)
	snm := ShortTypeName(typ)
	tr.Enums[snm] = typ
	if props != nil {
		nwprops := make(map[string]interface{}, len(props))
		for key, val := range props {
			nwprops[key] = val
		}
		tr.Props[snm] = nwprops
	}
	tp := tr.Properties(snm)
	tp["N"] = n
	if bitFlag {
		tp := tr.Properties(snm)
		tp["BitFlag"] = true
		EnumBitDepthCheck(typ, n)
	}
	return typ
}
func EnumBitDepthCheck(typ reflect.Type, n int64) error {
	cp := typ.Size() * 8
	if n > int64(cp) {
		err := fmt.Errorf("kit.EnumBitDepthCheck ERROR: enum: %v is a bitflag of kind: %v with capacity of: %d bits, but more flags were defined: %d", ShortTypeName(typ), typ.Kind(), cp, n)
		log.Println(err)
		return err
	}
	return nil
}
func (tr *EnumRegistry) AddEnumAltLower(en interface{}, bitFlag bool, props map[string]interface{}, prefix string) reflect.Type {
	typ := tr.AddEnum(en, bitFlag, props)
	n := EnumIfaceToInt64(en)
	snm := ShortTypeName(typ)
	alts := make(map[int64]string)
	tp := tr.Properties(snm)
	for i := int64(0); i < n; i++ {
		str := EnumInt64ToString(i, typ)
		str = strings.ToLower(strings.TrimPrefix(str, prefix))
		alts[i] = str
	}
	tp["AltStrings"] = alts
	return typ
}
func (tr *EnumRegistry) AddEnumExt(parTyp reflect.Type, en interface{}, bitFlag bool, props map[string]interface{}) reflect.Type {
	typ := tr.AddEnum(en, bitFlag, props)
	snm := ShortTypeName(typ)
	if parTyp == typ {
		log.Printf("kit.Enums.AddEnumExt: parent type: %v is same as type being defined -- must be different!\n", parTyp.String())
	} else {
		tr.SetProp(snm, "ParType", parTyp)
	}
	return typ
}
func (tr *EnumRegistry) AddEnumExtAltLower(parTyp reflect.Type, en interface{}, bitFlag bool, props map[string]interface{}, prefix string) reflect.Type {
	typ := tr.AddEnumExt(parTyp, en, bitFlag, props)
	n := EnumIfaceToInt64(en)
	snm := ShortTypeName(typ)
	alts := make(map[int64]string)
	tp := tr.Properties(snm)
	pnm := ShortTypeName(parTyp)
	pp := tr.Properties(pnm)
	pn, _ := ToInt(pp["N"])
	if palti, ok := pp["AltStrings"]; ok {
		palt := palti.(map[int64]string)
		for k, v := range palt {
			alts[k] = v
		}
	}
	for i := int64(pn); i < n; i++ {
		str := EnumInt64ToString(i, typ)
		str = strings.ToLower(strings.TrimPrefix(str, prefix))
		alts[i] = str
	}
	tp["AltStrings"] = alts
	return typ
}
func (tr *EnumRegistry) Enum(name string) reflect.Type {
	return tr.Enums[name]
}
func (tr *EnumRegistry) TypeRegistered(typ reflect.Type) bool {
	enumName := ShortTypeName(typ)
	_, ok := tr.Enums[enumName]
	return ok
}
func (tr *EnumRegistry) Properties(enumName string) map[string]interface{} {
	tp, ok := tr.Props[enumName]
	if !ok {
		tp = make(map[string]interface{})
		tr.Props[enumName] = tp
	}
	return tp
}
func (tr *EnumRegistry) Prop(enumName, propKey string) interface{} {
	tp, ok := tr.Props[enumName]
	if !ok {
		return nil
	}
	p, ok := tp[propKey]
	if !ok {
		return nil
	}
	return p
}
func (tr *EnumRegistry) SetProp(enumName, propKey string, val interface{}) {
	tp := tr.Properties(enumName)
	tp[propKey] = val
}
func (tr *EnumRegistry) AltStrings(enumName string) map[int64]string {
	ps := tr.Prop(enumName, "AltStrings")
	if ps == nil {
		return nil
	}
	m, ok := ps.(map[int64]string)
	if !ok {
		log.Printf("kit.EnumRegistry AltStrings error: AltStrings property must be a map[int64]string type, is not -- is instead: %T\n", m)
		return nil
	}
	return m
}
func (tr *EnumRegistry) ParType(enumName string) reflect.Type {
	pti := tr.Prop(enumName, "ParType")
	if pti == nil {
		return nil
	}
	pt, ok := pti.(reflect.Type)
	if !ok {
		log.Printf("kit.EnumRegistry ParType error: ParType property must be a reflect.Type, is not -- is instead: %T\n", pt)
		return nil
	}
	return pt
}
func (tr *EnumRegistry) NVals(eval interface{}) int64 {
	typ := reflect.TypeOf(eval)
	nm := ShortTypeName(typ)
	n := tr.Prop(nm, "N")
	if n != nil {
		return n.(int64)
	}
	log.Printf("kit.EnumRegistry: no N registered for type: %v\n", nm)
	return 0
}
func (tr *EnumRegistry) IsBitFlag(typ reflect.Type) bool {
	b, _ := ToBool(tr.Prop(ShortTypeName(typ), "BitFlag"))
	return b
}
func EnumIfaceToInt64(eval interface{}) int64 {
	ev := NonPtrValue(reflect.ValueOf(eval))
	var ival int64
	reflect.ValueOf(&ival).Elem().Set(ev.Convert(reflect.TypeOf(ival)))
	return ival
}
func SetEnumIfaceFromInt64(eval interface{}, ival int64, typ reflect.Type) error {
	if reflect.TypeOf(eval).Kind() != reflect.Ptr {
		err := fmt.Errorf("kit.SetEnumFromInt64: must pass a pointer to the enum: Type: %v, Kind: %v\n", reflect.TypeOf(eval).Name(), reflect.TypeOf(eval).Kind())
		log.Printf("%v", err)
		return err
	}
	reflect.ValueOf(eval).Elem().Set(reflect.ValueOf(ival).Convert(typ))
	return nil
}
func SetEnumValueFromInt64(eval reflect.Value, ival int64) error {
	if eval.Kind() != reflect.Ptr {
		err := fmt.Errorf("kit.SetEnumValueFromInt64: must pass a pointer value to the enum: Type: %v, Kind: %v\n", eval.Type().String(), eval.Kind())
		log.Printf("%v", err)
		return err
	}
	npt := NonPtrType(eval.Type())
	eval.Elem().Set(reflect.ValueOf(ival).Convert(npt))
	return nil
}
func EnumIfaceFromInt64(ival int64, typ reflect.Type) interface{} {
	evn := reflect.New(typ)
	SetEnumValueFromInt64(evn, ival)
	return evn.Elem().Interface()
}
func EnumIfaceToString(eval interface{}) string {
	strer, ok := eval.(fmt.Stringer)  
	if !ok {
		log.Printf("kit.EnumIfaceToString: fmt.Stringer interface not supported by type %v\n", reflect.TypeOf(eval).Name())
		return ""
	}
	return strer.String()
}
func EnumInt64ToString(ival int64, typ reflect.Type) string {
	ev := EnumIfaceFromInt64(ival, typ)
	return EnumIfaceToString(ev)
}
func EnumIfaceFromString(str string, typ reflect.Type) interface{} {
	evn := reflect.New(typ)
	SetEnumValueFromString(evn, str)
	return evn.Elem().Interface()
}
func (tr *EnumRegistry) EnumIfaceToAltString(eval interface{}) string {
	if reflect.TypeOf(eval).Kind() == reflect.Ptr {
		eval = reflect.ValueOf(eval).Elem()  
	}
	et := reflect.TypeOf(eval)
	tn := ShortTypeName(et)
	alts := tr.AltStrings(tn)
	if alts == nil {
		log.Printf("kit.EnumToAltString: no alternative string map for type %v\n", tn)
		return ""
	}
	ival := EnumIfaceToInt64(eval)
	return alts[ival]
}
func (tr *EnumRegistry) EnumInt64ToAltString(ival int64, typnm string) string {
	alts := tr.AltStrings(typnm)
	if alts == nil {
		log.Printf("kit.EnumInt64ToAltString: no alternative string map for type %v\n", typnm)
		return ""
	}
	return alts[ival]
}
func SetEnumValueFromString(eval reflect.Value, str string) error {
	etp := eval.Type()
	if etp.Kind() != reflect.Ptr {
		err := fmt.Errorf("kit.SetEnumValueFromString -- you must pass a pointer enum, not type: %v kind %v\n", etp, etp.Kind())
		return err
	}
	et := etp.Elem()
	methnm := "FromString"
	meth := eval.MethodByName(methnm)
	if ValueIsZero(meth) || meth.IsNil() {
		err := fmt.Errorf("kit.SetEnumValueFromString: stringer-generated FromString() method not found: %v for type: %v %T\n", methnm, et.Name(), eval.Interface())
		log.Printf("%v", err)
		return err
	}
	sv := reflect.ValueOf(str)
	args := make([]reflect.Value, 1)
	args[0] = sv
	meth.Call(args)
	return nil
}
func SetEnumIfaceFromString(eptr interface{}, str string) error {
	return SetEnumValueFromString(reflect.ValueOf(eptr), str)
}
func (tr *EnumRegistry) SetEnumValueFromAltString(eval reflect.Value, str string) error {
	etp := eval.Type()
	if etp.Kind() != reflect.Ptr {
		err := fmt.Errorf("kit.SetEnumValueFromString -- you must pass a pointer enum, not type: %v kind %v\n", etp, etp.Kind())
		log.Printf("%v", err)
		return err
	}
	et := etp.Elem()
	tn := ShortTypeName(et)
	alts := tr.AltStrings(tn)
	if alts == nil {
		err := fmt.Errorf("kit.SetEnumValueFromAltString: no alternative string map for type %v\n", tn)
		return err
	}
	for i, v := range alts {
		if v == str {
			return SetEnumValueFromInt64(eval, int64(i))
		}
	}
	err := fmt.Errorf("kit.SetEnumValueFromAltString: string: %v not found in alt list of strings for type%v\n", str, tn)
	return err
}
func (tr *EnumRegistry) SetEnumIfaceFromAltString(eptr interface{}, str string) error {
	return tr.SetEnumValueFromAltString(reflect.ValueOf(eptr), str)
}
func (tr *EnumRegistry) SetEnumValueFromStringAltFirst(eval reflect.Value, str string) error {
	err := tr.SetEnumValueFromAltString(eval, str)
	if err != nil {
		return SetEnumValueFromString(eval, str)
	}
	return err
}
func (tr *EnumRegistry) SetEnumIfaceFromStringAltFirst(eptr interface{}, str string) error {
	err := tr.SetEnumIfaceFromAltString(eptr, str)
	if err != nil {
		return SetEnumIfaceFromString(eptr, str)
	}
	return err
}
func BitFlagsToString(bflg int64, en interface{}) string {
	et := PtrType(reflect.TypeOf(en)).Elem()
	n := int(EnumIfaceToInt64(en))
	str := ""
	for i := 0; i < n; i++ {
		if bitflag.Has(bflg, i) {
			evs := EnumInt64ToString(int64(i), et)
			if str == "" {
				str = evs
			} else {
				str += "|" + evs
			}
		}
	}
	return str
}
func BitFlagsFromString(bflg *int64, str string, en interface{}) error {
	et := PtrType(reflect.TypeOf(en)).Elem()
	n := int(EnumIfaceToInt64(en))
	return BitFlagsTypeFromString(bflg, str, et, n)
}