package muesli

// MapValue is a Muesli value with a hash map.
// Maps in Muesli are heterogenous, and can contain other Values of any type.
// Furtehmore any Value can be used as the hash map key.
type MapValue struct {
	RedispatchCallable
	Map map[Value]Value
}

const MapType    		= TypeValue("Map")

func (v MapValue) Type() TypeValue    { return MapType }

func (val MapValue) String() string {
	res := "{"
	sep := ""
	for k, v := range val.Map {
		res = res + sep + k.String() + "=>" + v.String()
		sep = ", "
	}
	res += "}"
	return res
}


func NewMapValue(elements map[Value]Value) * MapValue {
	mv :=  &MapValue{Map:elements}
	mv.RedispatchCallable = NewRedispatchCallable("Map", mv)
	return mv
}

func (m *MapValue) Fetch(key Value) Value {
	var res Value
	var ok bool
	if res, ok = m.Map[key] ; !ok {
		return NilValue
	}
	return res
}

func (m *MapValue) Place(key Value, value Value) Value {
	m.Map[key] = value
	return m.Map[key]
}

func (from * MapValue) Convert(to interface{}) error {
	switch toPtr := to.(type) {
		case *map[Value]Value:
			(*toPtr) = from.Map
		case **MapValue:
			(*toPtr) = from
		case *Value:
			(*toPtr) = from			
		default:
			return NewErrorValuef("Cannot convert value %v to %v", from, to)
	}
	return nil
}