package basics.collections;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import basics.utl.Empty;
import basics.utl.SUtl;

/**
 * Bietet Methoden zu typisierten Lesen der Werte in einer Map an.
 * @author ks
 */
public class TypedValueMap
{
protected Map<String, Object> map;
private static final long     serialVersionUID = 1L;

public TypedValueMap()
{
   map = new HashMap<String, Object>();
}

// --- both: recursive and non-recursive (just current ctx) access ---------
public boolean containsKey(String key)
{
   return map.containsKey(key);
}

public void remove(String key)
{
   map.remove(key);
}

// ------ recursive access, go through ctx hierarchy ----------
public String get(String key, String defaultValue)
{
   Object v = map.get(key);
   return (Empty.is(v)) ? defaultValue : v.toString().trim();
}

public Object get(String key, Object defaultValue)
{
   Object v = map.get(key);
   return (v == null) ? defaultValue : v;
}

public int get(String key, int dv)
{
   return SUtl.toInt(map.get(key), dv);
}

public long get(String key, long dv)
{
   return SUtl.toLong(map.get(key), dv);
}

public boolean get(String key, boolean dv)
{
   return SUtl.toBoolean(map.get(key), dv);
}

public double get(String key, double dv)
{
   return SUtl.toDouble(map.get(key), dv);
}

public float get(String key, float dv)
{
   return (float)SUtl.toDouble(map.get(key), dv);
}

public TypedValueMap get(String key, TypedValueMap dv)
{
   TypedValueMap v = (TypedValueMap)map.get(key);
   return (v == null) ? dv : v;
}

// nicht recursive----------------------------
public void rename(String oldKey, String newKey)
{
   if(map.containsKey(oldKey))
   {
      map.put(newKey, map.get(oldKey));
      map.remove(oldKey);
   }
}

public void put(String key, String value)
{
   map.put(key, value);
}

public void put(String key, int value)
{
   map.put(key, value);
}

public void put(String key, boolean value)
{
   map.put(key, value);
}

public void put(String key, double value)
{
   map.put(key, value);
}

public void put(String key, float value)
{
   map.put(key, value);
}

public void put(String key, Object value)
{
   map.put(key, value);
}

public void put(String key, TypedValueMap value)
{
   map.put(key, value);
}

public String consume(String key, String dv)
{
   String v = get(key, dv);
   remove(key);
   return v;
}

public Object consume(String key, Object dv)
{
   Object v = get(key, dv);
   remove(key);
   return v;
}

public int consume(String key, int dv)
{
   int v = get(key, dv);
   remove(key);
   return v;
}

public boolean consume(String key, boolean dv)
{
   boolean v = get(key, dv);
   remove(key);
   return v;
}

public double consume(String key, double dv)
{
   double v = get(key, dv);
   remove(key);
   return v;
}

public float consume(String key, float dv)
{
   float v = get(key, dv);
   remove(key);
   return v;
}

@SuppressWarnings("unchecked")
public Set entrySet()
{
   return map.entrySet();
}

public Object get(Object key)
{
   return map.get(key);
}

public Set<String> keySet()
{
   return map.keySet();
}

@SuppressWarnings("unchecked")
public void putAll(Map map)
{
   for(Object k : map.keySet())
      map.put((String)k, map.get(k));
}

@SuppressWarnings("unchecked")
public Collection values()
{
   return map.entrySet();
}

public String toString()
{
   return SUtl.toString(map, null, true);
}

/**
 * does not clone errors!
 */
public TypedValueMap clone()
{
   TypedValueMap ctx = new TypedValueMap();
   for(String k : keySet())
      ctx.put(k, map.get(k));
   return ctx;
}

public int size()
{
   return map.size();
}

public boolean isEmpty()
{
   return map == null || map.size() < 1;
}

public Map<String, Object> getAsMap()
{
   Map<String, Object> out = new HashMap<String, Object>();
   for(String k : keySet())
      out.put(k, map.get(k));
   return out;
}
//public static void unittest ()
//{
//   
//}
///**
// * not arg0 supported here
// * @param properties
// * @return map
// */
//public static TMap createFromCmdLine (String properties)
//{
//   TMap map = new TMap();
//   InputParser parser = new InputParser(map);
//   parser.parse(properties);
//   return map;
//}
}
