func getType(some interface{}) reflect.Kind {
	return reflect.ValueOf(some).Kind()
}
get type  return (func, string ..)
package event
import (
	"fmt"
	"github.com/pkg/errors"
	"reflect"
)
const (
	typing    = "type"
	perform   = "perform"
	arguments = "arguments"
)
type Dispatcher struct {
	listeners map[string]map[int]map[string]interface{}
}
func New() *Dispatcher {
	d := &Dispatcher{}
	d.listeners = map[string]map[int]map[string]interface{}{}
	return d
}
func (dispatcher *Dispatcher) Add(name interface{}, performing interface{}, parameters ...interface{}) (flag bool, err error) {
	subscriber, err := factoryNames(name)
	if err == nil {
		flag = true
	}
	nameType := getType(performing)
	if _, exist := dispatcher.listeners[subscriber]; !exist {
		dispatcher.listeners[subscriber] = make(map[int]map[string]interface{})
	}
	dispatcher.listeners[subscriber][len(dispatcher.listeners[subscriber])] = map[string]interface{}{
		typing:    nameType.String(),
		perform:   performing,
		arguments: parameters,
	}
	return flag, err
}
func (dispatcher *Dispatcher) Go(event interface{}, parameters ...interface{}) (err error) {
	subscriber, err := factoryNames(event)
	if err != nil {
		return err
	}
	if dispatcher.existEvent(subscriber) {
		for _, iterate := range dispatcher.listeners[subscriber] {
			if parameters != nil {
				iterate[arguments] = parameters
			}
			resolver(iterate[typing].(string), iterate[perform], iterate[arguments].([]interface{}))
		}
	} else {
		panic(fmt.Sprintf(eventNotExist, subscriber))
	}
	return
}
func (dispatcher *Dispatcher) Fire(event interface{}, parameters ...interface{}) (err error) {
	return dispatcher.Go(event, parameters...)
}
func (dispatcher *Dispatcher) Destroy(event string) {
	if dispatcher.existEvent(event) {
		delete(dispatcher.listeners, event)
	} else {
		panic(fmt.Sprintf(eventNotExist, event))
	}
}
func (dispatcher *Dispatcher) Untie(pointer interface{}) {
	for _, event := range dispatcher.listeners {
		for key, iterate := range event {
			if reflect.ValueOf(iterate[perform]).Pointer() == reflect.ValueOf(pointer).Pointer() {
				delete(event, key)
			}
		}
	}
}
func (dispatcher *Dispatcher) existEvent(event string) bool {
	if _, exist := dispatcher.listeners[event]; exist {
		return true
	}
	return false
}
func (dispatcher *Dispatcher) existSubscriber(subscriber interface{}) bool {
	for _, event := range dispatcher.listeners {
		for _, iterate := range event {
			if reflect.ValueOf(iterate[perform]).Pointer() == reflect.ValueOf(subscriber).Pointer() {
				return true
			}
		}
	}
	return false
}
func GetName(structure interface{}) string {
	return reflect.TypeOf(structure).Name()
}
func factoryNames(value interface{}) (name string, err error) {
	typeOf := reflect.TypeOf(value)
	switch typeOf.Kind() {
	case reflect.Struct:
		name := typeOf.Name()
		if name != "" {
			return name, err
		}
		return "", errors.New(notFoundName)
	case reflect.String:
		if typeOf.Name() == typeOf.Kind().String() {
			return value.(string), err
		}
		return typeOf.Name(), err
	case reflect.Ptr:
		name := typeOf.Elem().Name()
		if name != "" {
			return name, err
		}
		return "", errors.New(notFoundName)
	default:
		if typeOf.Name() == typeOf.Kind().String() {
			return "", errors.New(notFoundName)
		}
		return typeOf.Name(), err
	}
}
func resolver(pointerType string, pointer interface{}, parameters []interface{}) {
	switch pointerType {
	case reflect.Func.String():
		in := make([]reflect.Value, len(parameters))
		for key, argument := range parameters {
			in[key] = reflect.ValueOf(argument)
		}
		value := reflect.ValueOf(pointer)
		value.Call(in)
	}
}